摘要:差異代表一個(gè)結(jié)果的兩個(gè)可能性,一個(gè)是,一個(gè)是代表可選擇的值,一個(gè)是代表有值,一個(gè)是值為空常用于結(jié)果可能為的情況運(yùn)算的結(jié)果有兩種情況,一個(gè)是運(yùn)行正常,即,一個(gè)是運(yùn)行出錯(cuò),拋出異常,即,其中里面包含的是異常的信息共同點(diǎn)三者都存在兩種可能性的值都
差異
Either
代表一個(gè)結(jié)果的兩個(gè)可能性,一個(gè)是 Right ,一個(gè)是 Left
Option
代表可選擇的值,一個(gè)是 Some(代表有值),一個(gè)是 None (值為空);常用于結(jié)果可能為 null 的情況;
Try
運(yùn)算的結(jié)果有兩種情況,一個(gè)是運(yùn)行正常,即 Success ,一個(gè)是運(yùn)行出錯(cuò),拋出異常 ,即 Failure ,其中 Failure 里面包含的是異常的信息;
共同點(diǎn)
三者都存在兩種可能性的值;都可以在結(jié)果之上進(jìn)行 map 、 flatMap 等操作;
Either
Right 和 Left 是繼承自 Either 的兩個(gè) case 類;
//Left final case class Left[+A, +B](@deprecatedName("a, "2.12.0") value: A) extends Either[A, B] //Right final case class Right[+A, +B](@deprecatedName("b, "2.12.0") value: B) extends Either[A, B]
Eihter 代表一個(gè)結(jié)果的兩個(gè)可能性,一個(gè)是 Right ,一個(gè)是 Left ;
import scala.io.StdIn._ val in = readLine("Type Either a string or an Int: ") val result: Either[String,Int] = try Right(in.toInt) catch { case e: NumberFormatException => Left(in) } result match { case Right(x) => s"You passed me the Int: $x, which I will increment. $x + 1 = ${x+1}" case Left(x) => s"You passed me the String: $x" }
Either 是偏向 Right 值的,在 Either 使用 map 、flatMap 等操作時(shí),只有 Either 的結(jié)果是 Right 時(shí),才會(huì)觸發(fā)操作;習(xí)慣性地將Left 值代表不好的結(jié)果(失敗的結(jié)果),Right 代表好的結(jié)果(成功的結(jié)果);
def doubled(i: Int) = i * 2 Right(42).map(doubled) // Right(84) Left(42).map(doubled) // Left(42)
由于Either 定義了 flatMap 和 map ,所以可以對(duì) Either 使用 for comprehensions;
val right1 = Right(1) : Right[Double, Int] //確定right1的類型 val right2 = Right(2) val right3 = Right(3) val left23 = Left(23.0) : Left[Double, Int] //確定left23的類型 val left42 = Left(42.0) for { x <- right1 y <- right2 z <- right3 } yield x + y + z // Right(6) for { x <- right1 y <- right2 z <- left23 } yield x + y + z // Left(23.0) for { x <- right1 y <- left23 z <- right2 } yield x + y + z // Left(23.0)
但是不支持使用守衛(wèi)表達(dá)式
for { i <- right1 if i > 0 } yield i // error: value withFilter is not a member of Right[Double,Int]
同樣,下面也是不支持的
for (x: Int <- right1) yield x // error: value withFilter is not a member of Right[Double,Int]
由于 for comprehensions 使用 map 和 flatMap ,所以必須要推導(dǎo)參數(shù)的類型,并且該類型必須是 Either ;特別的地方在于,由于Either 是偏向Right 的,所以是對(duì)于Either的值為Left必須要指定其類型,否則,該位置的默認(rèn)類型為Nothing;
for { x <- left23 y <- right1 z <- left42 // type at this position: Either[Double, Nothing] } yield x + y + z // ^ // error: ambiguous reference to overloaded definition, // both method + in class Int of type (x: Char)Int // and method + in class Int of type (x: Byte)Int // match argument types (Nothing) for (x <- right2 ; y <- left23) yield x + y // Left(23.0) for (x <- right2 ; y <- left42) yield x + y // error for { x <- right1 y <- left42 // type at this position: Either[Double, Nothing] z <- left23 } yield x + y + z // Left(42.0), but unexpectedly a `Either[Double,String]`
Option
Some 和 None 是繼承自 Option 的兩個(gè) case 類;
//Some final case class Some[+A](@deprecatedName("x, "2.12.0") value: A) extends Option[A] //None case object None extends Option[Nothing]
對(duì)Option 的習(xí)慣用法是把它當(dāng)作集合或者monad ,通過(guò)map 、flatMap 、filter 和 foreach :
//方式一 val name: Option[String] = request getParameter "name" val upper = name map { _.trim } filter { _.length != 0 } map { _.toUpperCase } println(upper getOrElse "") //方式一等價(jià)于方式二 val upper = for { name <- request getParameter "name" //由于For表達(dá)式的作用,如何此處返回None,那么整個(gè)表達(dá)式將返回None trimmed <- Some(name.trim) upper <- Some(trimmed.toUpperCase) if trimmed.length != 0 } yield upper println(upper getOrElse "")
另外一個(gè)習(xí)慣用法是(不太推薦)通過(guò)模式匹配:
val nameMaybe = request getParameter "name" nameMaybe match { case Some(name) => println(name.trim.toUppercase) case None => println("No name value") }
Try
Failure 和 Success 是繼承自 Try 的兩個(gè) case 類;
//Failure final case class Failure[+T](exception: Throwable) extends Try[T] //Success final case class Success[+T](value: T) extends Try[T]
Try 常用于那些存在異常的地方,通過(guò)Try 不用確定地對(duì)可能出現(xiàn)的異常進(jìn)行處理;
import scala.io.StdIn import scala.util.{Try, Success, Failure} def divide: Try[Int] = { val dividend = Try(StdIn.readLine("Enter an Int that you"d like to divide: ").toInt) val divisor = Try(StdIn.readLine("Enter an Int that you"d like to divide by: ").toInt) val problem = dividend.flatMap(x => divisor.map(y => x/y)) problem match { case Success(v) => println("Result of " + dividend.get + "/"+ divisor.get +" is: " + v) Success(v) case Failure(e) => println("You must"ve divided by zero or entered something that"s not an Int. Try again!") println("Info from the exception: " + e.getMessage) divide } }
在上面的例子中,可以看出 Try 的一個(gè)重要的特性,就是Try 具有管道的功能 ,flatMap 和 map 將那些成功完成的操作的結(jié)果包裝成Success ,將那些異常包裝成 Failure ,而對(duì)于 recover 和 recoverWith 則是默認(rèn)對(duì) Failure 結(jié)果進(jìn)行觸發(fā);
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/71147.html
摘要:復(fù)制代碼報(bào)錯(cuò)信息如下錯(cuò)誤錯(cuò)誤解答執(zhí)行命令安裝依賴包。為了讓讀者理解問(wèn)題,重現(xiàn)上述錯(cuò)誤過(guò)程,命令如下復(fù)制代碼1、Nginx安裝過(guò)程報(bào)錯(cuò)錯(cuò)誤一:軟件依賴包未正確安裝問(wèn)題---PCRE依賴包沒(méi)有安裝 ./configure: error: the HTTP rewrite module requires the PCRE library. You can either disable the...
摘要:在深入理解中的變量上中我們看到的引入,使得可以很方便地在多線程環(huán)境中使用局部變量。特別需要注意的是,基類的并不會(huì)屏蔽派生類中的創(chuàng)建。到此,整個(gè)源碼核心部分已經(jīng)理解的差不多了,只剩下用來(lái)執(zhí)行清除工作。 在 深入理解Python中的ThreadLocal變量(上) 中我們看到 ThreadLocal 的引入,使得可以很方便地在多線程環(huán)境中使用局部變量。如此美妙的功能到底是怎樣實(shí)現(xiàn)的?如果你...
摘要:在中也可以看到執(zhí)行記錄,包括錯(cuò)誤信息解讀生命周期在任務(wù)開(kāi)始之前即在初始化之后執(zhí)行任何或?qū)崿F(xiàn)之前創(chuàng)建一個(gè)記錄記錄開(kāi)始事件的條目,此事件由觸發(fā),來(lái)向系統(tǒng)指出所有都可以使用。在加載完成所有的之后,任務(wù)執(zhí)行并更新數(shù)據(jù)庫(kù)中的執(zhí)行結(jié)果和狀態(tài),最后退出。 起步:什么是 spring cloud task Spring Cloud Task makes it easy to create short ...
摘要:源碼漫游二描述在一中其實(shí)已經(jīng)把作為的框架中數(shù)據(jù)流相關(guān)跑了一遍??瓷厦鎯膳殴卜椒ㄟ@個(gè)方法的調(diào)用在整個(gè)源碼中就兩處,和。過(guò)程,這也是導(dǎo)致我們?cè)谠创a運(yùn)行中總是看見(jiàn)在有無(wú)函數(shù)分支,的時(shí)候總是能看見(jiàn)函數(shù),然后就進(jìn)入對(duì)組件。 Vue2 源碼漫游(二) 描述: 在(一)中其實(shí)已經(jīng)把Vue作為MVVM的框架中數(shù)據(jù)流相關(guān)跑了一遍。這一章我們先看mount這一步,這樣Vue大的主線就基本跑通了。...
閱讀 2270·2023-04-25 14:50
閱讀 1265·2021-10-13 09:50
閱讀 1872·2019-08-30 15:56
閱讀 1847·2019-08-29 15:29
閱讀 2891·2019-08-29 15:27
閱讀 3557·2019-08-29 15:14
閱讀 1201·2019-08-29 13:01
閱讀 3305·2019-08-26 14:06