我很困惑。在TraversableLike
中,有一个带有签名
flatMap
flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): Iterable[B]
但是,我可以这样使用
scala> Iterable(1,2,3,4,5).flatMap{i=>if (i%2==0) {None} else {Some(i)}}
res1: Iterable[Int] = List(1, 3, 5)
为什么可能? Option
如何转换为GenTraversableOnce
?它似乎不是一个子类...
答案 0 :(得分:19)
正如您在类图(*)中看到的那样,Option
不是GenTraversableOnce
的子类,但Iterable
可以使用隐式转换,{{1} }}
(*)是的,好吧,我作弊了。 Scaladoc上没有类图...但它们应该是明天! : - )
答案 1 :(得分:16)
实际上默认情况下从Some [X]到GenTraversableOnce [X]进行隐式转换。这在REPL
中测试非常简单scala> implicitly[Function[Some[Int],GenTraversableOnce[Int]]]
res1: Some[Int] => scala.collection.GenTraversableOnce[Int] = <function1>
scala> implicitly[Some[Int] => GenTraversableOnce[Int]] // alternative syntax
res2: Some[Int] => scala.collection.GenTraversableOnce[Int] = <function1>
实际上这是在对象Option中定义的。内部scala包:
object Option {
/** An implicit conversion that converts an option to an iterable value
*/
implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList
/** An Option factory which creates Some(x) if the argument is not null,
* and None if it is null.
*
* @param x the value
* @return Some(value) if value != null, None if value == null
*/
def apply[A](x: A): Option[A] = if (x == null) None else Some(x)
/** An Option factory which returns `None` in a manner consistent with
* the collections hierarchy.
*/
def empty[A] : Option[A] = None
}
option2Iterable正是您所寻找的。您还可以看到为什么在REPL中进行测试时可以看到GenTraversableOnce的实现是一个列表。
如果您正在寻找在没有做任何事情的情况下自动导入的隐式转换(例如您可以隐式使用REPL中看到的转换),您必须查看:
答案 2 :(得分:3)
似乎确实隐式转换为List
。
scala> val l:scala.collection.GenTraversableOnce[Int] = Some(3)
l: scala.collection.GenTraversableOnce[Int] = List(3)
scala> val l:scala.collection.GenTraversableOnce[Int] = None
l: scala.collection.GenTraversableOnce[Int] = List()
个人提示:scala magic隐式转换有时会让人感到困惑。