Option
可以被视为一个包含零个或一个元素的集合,它提供了一定程度的与 scala.collection
包中找到的集合类型之间的互操作性。特别是,它实现了 IterableOnce
接口,该接口模拟了集合的最简单形式:至少可以迭代一次的东西。但是,Option
没有实现 Iterable
的更全面的接口。实际上,我们无法为 fromSpecific
操作提供合理的实现,该操作应该从可能包含多个元素的集合中创建 Option
。从 Scala 2.13 开始,Option
被设置为 IterableOnce
,但不是 Iterable
。
因此,Option
可以用在任何需要 IterableOnce
的地方,例如,在对集合调用 flatMap
时(或在 for 理解中)。
for {
a <- Set(1)
b <- Option(41)
} yield (a + b)
// : Set[Int] = Set(42)
for
a <- Set(1)
b <- Option(41)
yield (a + b)
// : Set[Int] = Set(42)
由于类型 Set[Int]
上的 flatMap
操作需要一个返回 IterableOnce
的函数
def flatMap[B](f: Int => IterableOnce[B]): Set[B]
虽然 Option
没有扩展 Iterable
,但存在一个 隐式转换,将 Option
转换为 Iterable
implicit def option2Iterable[A](xo: Option[A]): Iterable[A]
因此,虽然 Option[A]
不是一个完整的集合,但它可以被视为一个集合。例如,
Some(42).drop(1)
// : Iterable[Int] = List()
扩展为
Option.option2Iterable(Some(42)).drop(1)
// : Iterable[Int] = List()
因为 drop
在 Option
上没有定义。上述隐式转换的一个缺点是,我们最终得到的是一个 Iterable[A]
,而不是一个 Option[A]
。出于这个原因,Option
的文档中包含以下说明
Option
中的许多方法与Iterable
层次结构中的方法重复,但它们是出于某种原因重复的:隐式转换往往会让人在本来可以保留Option
的情况下得到一个Iterable
。