集合

Option 和集合之间的转换

语言

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()

因为 dropOption 上没有定义。上述隐式转换的一个缺点是,我们最终得到的是一个 Iterable[A],而不是一个 Option[A]。出于这个原因,Option 的文档中包含以下说明

Option 中的许多方法与 Iterable 层次结构中的方法重复,但它们是出于某种原因重复的:隐式转换往往会让人在本来可以保留 Option 的情况下得到一个 Iterable

本页贡献者