理解中的選項
Option
s 有一個 flatMap
方法。這意味著它們可以用於理解。通過這種方式,我們可以解除常規功能,無需重新定義它們即可在 Option
上執行。
val firstOption: Option[Int] = Option(1)
val secondOption: Option[Int] = Option(2)
val myResult = for {
firstValue <- firstOption
secondValue <- secondOption
} yield firstValue + secondValue
// myResult: Option[Int] = Some(3)
當其中一個值是 None
時,計算的結束結果也將是 None
。
val firstOption: Option[Int] = Option(1)
val secondOption: Option[Int] = None
val myResult = for {
firstValue <- firstOption
secondValue <- secondOption
} yield firstValue + secondValue
// myResult: Option[Int] = None
注意:此模式更廣泛地適用於名為 Monad
s 的概念。 (有關理解和 Monad
s 的頁面應提供更多資訊)
通常,為了便於理解,不可能混合不同的單子。但是由於 Option
可以輕鬆轉換為 Iterable
,我們可以通過呼叫 .toIterable
方法輕鬆混合 Option
s 和 Iterable
s。
val option: Option[Int] = Option(1)
val iterable: Iterable[Int] = Iterable(2, 3, 4, 5)
// does NOT compile since we cannot mix Monads in a for comprehension
// val myResult = for {
// optionValue <- option
// iterableValue <- iterable
//} yield optionValue + iterableValue
// It does compile when adding a .toIterable on the option
val myResult = for {
optionValue <- option.toIterable
iterableValue <- iterable
} yield optionValue + iterableValue
// myResult: Iterable[Int] = List(2, 3, 4, 5)
一個小注釋:如果我們已經定義了我們的理解,那麼圍繞 for comprehension 的另一種方式會編譯,因為我們的選項會被隱式轉換。因此,始終新增此 .toIterable
(或相應的功能取決於你使用的集合)以保持一致性非常有用。