immutable.Map.map如何运作?看起来文档有问题:
def map[B](f: (A) ⇒ B): Map[B]
[用例]通过将函数应用于此不可变映射的所有元素来构建新集合。
完整签名
def map[B, That](f: ((A, B)) ⇒ B)(implicit bf: CanBuildFrom[Map[A, B], B, That]): That
Map[B]
没有意义,因为Map
有两个类型参数。B
的类型参数map
与B
的类型参数Map
之间存在名称冲突。可以理解的混淆源于map
没有在Map
中实现,而是在TraversableLike
中实现。但是,子类继承的函数文档。
TraversableLike
采用两个类型参数TraversableLike[+A, +Repr]
,地图函数具有签名TraversableLike.map[B](f: (A) ⇒ B): Traversable[B]
。在Map
的api文档中,Traversable[B]
继承并部分调整了Map[B]
的文档,但来自B
的TraversableLike
未解析为(A, B)
形式Map
。
(可能是Scaladoc中的一个错误,可能无法修复,因为可能存在擦除问题。但这只是猜测我。)
如果在成员文档正上方配置成员的可见性,则可以检查Map
中实际实现的内容。
编辑:
现在回答你的核心问题:
如果文档会给我们,我们可以直观地阅读
如果我们为了可读性而简化它
如果我们进一步使用更多的自然语言而不是首字母缩略词,Map[A, B]
的地图签名可能如下所示:
map[ResultItem, ResultCollection](f: (A,B) => ResultItem)(implicit bf: CanBuildFrom[Map[A, B], ResultItem, ResultCollection]): ResultCollection
因此,基本上你将一个函数应用于Map
的每个键值对,它将类型(A,B)的键值对转换为类型为ResultType
的值。
由于您可以从地图(或任何其他集合)构建几乎任何类型的集合,因此此结果类型不必是另一个元组。 ResultCollection
不一定是另一个Map
。例如。:
Map("1" -> 1, "2" -> 2).map((keyValuePair: (String, Int)) => keyValuePair._2)
或短
Map("1" -> 1, "2" -> 2).map(_._2)
将List(1, 2)
作为结果,List[Int]
作为ResultCollection,Int
作为ResultItem。
这是可能的,因为隐式CanBuildFrom
参数添加了一个隐式构建器,该构建器获取map函数的结果并将其附加到其构建器结果。在大多数情况下,CanBuildFrom
是由编译器推断的。但是,有些情况下无法推断出正确的结果集合。
在这种情况下,您必须为编译器提供更多信息:
val test2: Vector[Int] = Map("1" -> 1, "2" -> 2).map(_._2)(collection.breakOut)
val test3: Set[Int] = Map("1" -> 1, "2" -> 2).map(_._2)(collection.breakOut)
有关breakOut
和CanBuildFrom
的更多信息,我建议使用this answer