【问题标题】:difference between map and flatMap in scalascala中map和flatMap的区别
【发布时间】:2017-07-26 05:38:16
【问题描述】:

地图和平面地图有什么区别?就像我们可以做一个

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。

【问题讨论】:

标签: scala


【解决方案1】:

让我们看看flatMap的签名。

def flatMap[B](f: (Int) ⇒ GenTraversableOnce[B]): TraversableOnce[B]

map的签名

def map[B](f: (A) ⇒ B): IndexedSeq[B]

可以看到f 的结果类型必须是GenTraversableOnce[B] 对于flatMap。 但是对于mapf 的结果类型没有限制。

println(x) 的结果类型为Unitx+2 的结果类型为Int。因为两者都没有实现GenTraversableOnce[B],所以你不能做flatMap(x=>println(x))也不能做flatMap(x=>x+2)

另一方面,Some(i)None 的类型为 Option[Int],可以隐式转换为 Iterable[Int] source

Iterable的签名是

trait Iterable[+A] extends Traversable[A]

Traversable

trait Traversable[+A] .. with TraversableOnce[A]`

最后是TraversableOnce

trait TraversableOnce[+A] extends GenTraversableOnce[A]

因此Option[Int] 实现了GenTraversableOnce[Int],因此您可以将其用作flatMap[Int] 的结果

【讨论】:

    【解决方案2】:

    错误是:

    类型不匹配,预期:(int) => GenTraverableOnce[NotInferedB], 实际:(int) => 单位

    因为flatMapmapflatten 的组合。所以flatMap 会在序列的每个元素上运行 map,然后运行 ​​flatten。

    例如:[1,2][2,3] --> [1,2,2,3]

    Scala 不能用 Unit 类型做到这一点。从技术上讲,因为 Unit 没有实现 GenTraverableOnceOption 也不是,但Option[A] 可以隐式转换为Iterable[A],即GenTraverableOnce[A]。这是reference

    【讨论】:

    • 感谢您的帮助。为什么这不起作用,然后 flatMap(x => x + 2) 像 map(x => x + 2) 一样起作用?也许你已经提到过,但我没有得到答案。
    • flatMap(x => x + 2)还是不行,因为此时的签名是:flatMap[Int, Int]。但是 Int 没有实现GenTraversableOncemap 没有这个限制。您可以从任意类型 A 映射到任意类型 B。
    • 你可以flatMap(x => Some(x)),因为此时flatMap的签名是flatMap[Int, Option]。但是Option[A] 可以隐式转换为GenTraverableOnce[A]。你可以在这个链接上看到:stackoverflow.com/questions/11429360/…
    猜你喜欢
    • 1970-01-01
    • 2018-09-12
    • 2011-10-05
    • 1970-01-01
    • 2014-12-28
    • 2019-04-01
    • 2010-11-06
    • 2018-08-23
    相关资源
    最近更新 更多