假設我有一系列獨立的計算,需要在最后進行組合:
def makeSauce()。 Try[Sauce] = Sauce("marinara")
def makeCrust()。 Try[Crust] = Failure(new RuntimeException("stale bread"/span>)
def makeCheese()。Try[Cheese] = Failure(new IllegalArgumentException("mody cheese")
for {
醬汁 <- makeSauce()
地殼 <- makeCrust()
奶酪 <- makeCheese()
} yield {
Pizza( sauce, crust, cheese)
但是如果我的任何計算失敗,我想要一個全面的錯誤資訊,描述所有的失敗,而不僅僅是第一個。上面的代碼并沒有做到我想要的,它只向我顯示了第一個失敗("陳舊的面包")。相反,它應該拋出一個超級錯誤資訊,將其他兩個錯誤資訊結合起來,這可能是一連串的例外物件、一連串的字串錯誤資訊,甚至只是一個巨大的串聯字串。
另外,也可以不拋出例外,而是將其組成一個頂級的Failure物件:
(for {
sauce <- makeSauce()
地殼 <- makeCrust()
奶酪 <- makeCheese()
} yield ( sauce, crust, cheese)) match {
case Success((sauce, crust, cheese)) => Pizza( sauce, crust, cheese)
case Failure(e) => throw e
}
這里的for-comprehension和Try只是為了說明,一個有效的解決方案不一定要使用for或Try。然而,很明顯,上述語法是有表現力的,并且幾乎做了我想要的事情,所以理想情況下,解決方案將盡可能地堅持使用它。
我怎樣才能在 Scala 中實作這樣的目標呢?
uj5u.com熱心網友回復:
scala.util.Try的行為方式是失敗快速的。在for-comprehension背景關系中,它按順序執行,并在第一次失敗時停止。
你需要的是一個聚合所有失敗的結構,比如cats.data.Validated或者scalaz.Validation。
uj5u.com熱心網友回復:
Validated是你正在尋找的東西。例如,它就在Cats中。
import cats.data.Validated。
import cats.implicits.catsSyntaxTuple3Semigroupal
def valid(input: String) = if (input. toIntOption.isEmpty) Validated.Invalid(s"$input is not a number")
else Validated.Valid(input.toInt)
def sumThreeNumbers(one:String, two:String, three: String)=(valid(one), valid(two), valid(three)).mapN((oneInt, twoInt, threeInt)=> oneInt twoInt threeInt)
sumThreeNumbers("1"/span>,"2"/span>,"3"/span>)
sumThreeNumbers("1"/span>,"2"/span>,"xxx"/span>)
//results //results
val res0: cats.data. Validated[String,Int] = Valid(6)
val res1: cats.data.Validated[String,Int] = Invalid(2不是一個數字。xxx不是一個數字。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/309122.html
標籤:
