map和flatMap有什么区别?正如我们可以做的那样
1 to 5 map(c => println(c))
但不是
1 to 5 flatMap(c => println(c))
另一方面,这是有效的
def h(i: Int) = if (i >= 2) Some(i) else None
1 to 5 flatMap(h)
我知道flatMap是map和flatten,但不确定何时可以使用map并且可以使用flatMap。
答案 0 :(得分:6)
让我们看一下flatMap的签名。
def flatMap[B](f: (Int) ⇒ GenTraversableOnce[B]): TraversableOnce[B]
和map
的签名def map[B](f: (A) ⇒ B): IndexedSeq[B]
您可以看到f
的结果类型GenTraversableOnce[B]
必须为flatMap
。
但f
map
的结果类型没有限制。
println(x)
的结果类型为Unit
,结果类型x+2
为Int
。由于两者都未实现GenTraversableOnce[B]
,因此您无法flatMap(x=>println(x))
或flatMap(x=>x+2)
。
另一方面,Some(i)
和None
的{{1}}类型可以隐式转换为Option[Int]
source
Iterable的签名是
Iterable[Int]
trait Iterable[+A] extends Traversable[A]
trait Traversable[+A] .. with TraversableOnce[A]`
因此trait TraversableOnce[+A] extends GenTraversableOnce[A]
实施Option[Int]
,因此您可以将其用作GenTraversableOnce[Int]
答案 1 :(得分:1)
错误是:
类型不匹配,预期:(int)=> GenTraverableOnce [NotInferedB] 实际:(int)=>单元
因为flatMap
是map
和flatten
的组合。所以flatMap
将在序列的每个元素上运行map,然后运行flatten。
例如:[1,2][2,3]
- > [1,2,2,3]
Scala无法使用类型Unit执行此操作。从技术上讲,因为Unit没有实现GenTraverableOnce
。 Option
也没有,但Option[A]
可以隐式转换为Iterable[A]
,即GenTraverableOnce[A]
。这是reference