理解中的選項

Options 有一個 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

注意:此模式更廣泛地適用於名為 Monads 的概念。 (有關理解和 Monads 的頁面應提供更多資訊)

通常,為了便於理解,不可能混合不同的單子。但是由於 Option 可以輕鬆轉換為 Iterable,我們可以通過呼叫 .toIterable 方法輕鬆混合 Options 和 Iterables。

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(或相應的功能取決於你使用的集合)以保持一致性非常有用。