Option
可視為一個具有零個或恰好一個元素的集合,且它提供了一定程度的互操作性,與套件 scala.collection
中找到的集合類型相容。特別是,它實作介面 IterableOnce
,它建構了最簡單形式的集合:可以反覆運算,至少一次。然而,Option
沒有實作更全面的介面 Iterable
。事實上,我們無法為操作 fromSpecific
提供明智的實作,此操作應從一個可能包含多個元素的集合建立一個 Option
。從 Scala 2.13 開始,Option
已成為 IterableOnce
,但不是 Iterable
。
因此,當預期 IterableOnce
時,可以在任何地方使用 Option
,例如,在集合上呼叫 flatMap
時(或在 for-comprehension 內部)
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
中。上述隱式轉換的缺點是,我們得到的不是 Option[A]
,而是一個 Iterable[A]
。基於這個原因,Option
的文件包含下列註解
Option
中的許多方法與Iterable
層級中的方法重複,但重複是有原因的:隱式轉換傾向於在原本可以保留Option
的情況下,留下一個Iterable
。