我遇到了Scala的一个奇怪功能,其中以下两个不相同:
var map = Map[A,B]()
map += ( key -> (valueGen(key)))
与
的结果不同var map = Map[A,B]()
val result = valueGen(key)
map += ( key -> result)
第二个代码段执行您期望的操作,而第一个代码段未正确添加到地图中,而是覆盖先前的值,以便地图仅包含最近写入的值而不是添加到的所有值它
答案 0 :(得分:3)
我以前见过这个,当valueGen
函数和这段代码一起递归时,它只会导致问题。我相信这是因为括号中的表达式不能保证首先执行。括号仅绑定运算符。 Scala必须像这样解释地图上的+ =:
map = map + (expression)
当它执行map + (expression)
时,它首先将地图操作数读取到加号运算符并保存它。然后它尝试评估(expression)
。在(expression)
包含对valueGen
函数的调用的情况下,它会进行调用,然后将其添加到此特定调用的缓存映射中。如果对valueGen
的调用最终递归并调用此函数(并首先修改映射),则会使用此调用中的缓存版本+结果覆盖这些更改。这就是为什么如果函数是递归的,你想要从+ =运算符中单独调用valueGen
函数。
答案 1 :(得分: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)
你能提供你所看到的可运行的例子吗?