理解中的选项
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
(或相应的功能取决于你使用的集合)以保持一致性非常有用。