看起来 - 在Scala 2.8.0中 - 如果你将Map实例映射到一个2元组的序列,你最终会得到一个Map。当发生这种情况时,任何具有相同第一个元素的2元组都被视为重复元素,并且您最终只能得到最后一个元素。这与2.7.7中发生的情况不同。通过示例更容易理解。
Scala 2.7.7:
scala> val m = Map("a" -> 1, "b" -> 2, "c" -> 3)
m: scala.collection.immutable.Map[java.lang.String,Int] = Map(a -> 1, b -> 2, c -> 3)
scala> m.map { case (k, v) => ("foo", v) }
res5: Iterable[(java.lang.String, Int)] = ArrayBuffer((foo,1), (foo,2), (foo,3))
Scala 2.8.0:
scala> val m = Map("a" -> 1, "b" -> 2, "c" -> 3)
m: scala.collection.immutable.Map[java.lang.String,Int] = Map((a,1), (b,2), (c,3))
scala> m.map { case (k, v) => ("foo", v) }
res16: scala.collection.immutable.Map[java.lang.String,Int] = Map((foo,3))
这是预期的吗?变更是否记录在某处?这似乎是一个合理的想法,但是我花了很多时间来升级依赖于旧行为的2.7.7应用程序。
更新:
正如Kris Nuttycombe在下面指出的那样,在提出这个问题之前阅读Migrating from Scala 2.7可能是一个好的开始:)特别是它提到使用编译器标志-Xmigration
,这在移植时似乎非常有用。
答案 0 :(得分:7)
是的,这是预期的行为;实际上,启用此类功能是2.8中重新设计系列系统的重点。默认情况下,Scala将在应用map函数时选择最具体的类型;但是,如果你需要迭代(例如,因为你担心通过重复键消除值,最简单的事情可能是简单地在地图上调用toSeq:
scala> val iter = m.toSeq.map { case (k, v) => ("foo", v) }
iter: Seq[(java.lang.String, Int)] = List((foo,1), (foo,2), (foo,3))
就记录而言,这里有广泛的讨论:http://www.scala-lang.org/node/2060和(更多)这里:http://www.scala-lang.org/docu/files/collections-api/collections.html