0

我遇到了 Scala 的一个奇怪的功能,其中以下两个不等价:

var map = Map[A,B]() 
map += ( key -> (valueGen(key)))

没有给出相同的结果

var map = Map[A,B]() 
val result = valueGen(key)
map += ( key -> result)

第二个片段执行您期望的操作,而第一个片段没有正确添加到地图中,而是覆盖了以前的值,以便地图只包含最近写入的值,而不是添加到其中的所有值。

4

2 回答 2

3

我以前见过这个,只有当valueGen函数和这段代码一起递归时才会导致问题。我相信这是因为括号中的表达式不能保证首先执行。括号仅绑定运算符。Scala 必须像这样解释地图上的 +=:

map = map + (expression)

当它执行时map + (expression),它首先将映射操作数读取到加号运算符并保​​存。然后它尝试评估(expression). 在(expression)包含对该valueGen函数的调用的情况下,它会进行调用,然后将其添加到此特定调用的缓存映射中。如果调用valueGen最终递归并调用此函数(并首先修改地图),这将使用此调用的缓存版本+结果覆盖这些更改。这就是为什么如果您的函数是递归的,您希望将valueGen函数与 += 运算符分开调用。

于 2012-05-31T05:13:06.973 回答
1

当我跑

object test {
    def main(args: Array[String]) {
        var map = Map[String,Int]()
        map += ("hello" -> (valueGen("hello")))
        map += ("bye" -> (valueGen("bye")))
        println(map)
    }

    def valueGen(x: String) = x.length
}

我明白了

Map(hello -> 5, bye -> 3)

您能否提供一个可运行的示例来说明您所看到的内容?

于 2012-05-31T05:11:37.293 回答