我无法弄清楚Scala编译器如何使用flatMap
的序列来计算Option
。
如果我对序列序列使用flatMap
:
println(Seq(Seq(1), Seq()).flatMap(a => a)) // List(1)
它将连接所有嵌套序列
如果我将其与Option
s:
println(Seq(Some(1), None).flatMap(a => a)) // List(1)
因此flatMap
将Option
视为此案例中的集合。问题是为什么这有效? flatMap
具有以下定义:
def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That
这意味着它需要一个返回GenTraversableOnce
实例的函数,但Option
不会继承GenTraversableOnce
。它仅继承Product
和Serializable
,Product
继承Equals
。
在这种情况下,Scala编译器如何在flatMap
的序列上使用Option
?
答案 0 :(得分:4)
你的观察是正确的。在这种情况下,如果编译器不能匹配该类型,它会查找隐式转换并在Option
的伴随对象中找到一个:
import scala.language.implicitConversions
/**
An implicit conversion that converts an option to an iterable value
*/
implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList
这样就可以将Option
视为Iterable
s。
此外,您的代码可以使用flatten
简化:
Seq(Some(1), None).flatten