为什么“flatMap”在 Scala 中使用 Option 类型的序列?

Iva*_*tyk 6 scala optional flatmap

我无法弄清楚 Scala 编译器如何弄清楚如何使用sflatMap序列Option

如果我flatMap在一系列序列上使用 a :

println(Seq(Seq(1), Seq()).flatMap(a => a)) // List(1)
Run Code Online (Sandbox Code Playgroud)

它将连接所有嵌套序列

如果我将它与一系列Options一起使用,也会发生同样的情况:

println(Seq(Some(1), None).flatMap(a => a)) // List(1)
Run Code Online (Sandbox Code Playgroud)

因此,在这种情况下,flatMapOption视为集合。问题是为什么这样做?该flatMap定义如下:

def flatMap[B, That](f: A => GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That
Run Code Online (Sandbox Code Playgroud)

这意味着它需要一个返回 实例的函数GenTraversableOnce,但Option不继承GenTraversableOnce。它只继承ProductSerializable,并Product继承Equals

在这种情况下,Scala 编译器如何使用sflatMap的序列Option

Grz*_*rek 6

你的观察是对的。在这种情况下,如果编译器无法匹配类型,它会查找隐式转换并在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
Run Code Online (Sandbox Code Playgroud)

这使得可以将Options 视为Iterables。


此外,可以使用flatten以下方法简化您的代码:

Seq(Some(1), None).flatten
Run Code Online (Sandbox Code Playgroud)