【发布时间】:2013-10-08 23:50:38
【问题描述】:
我一直在用可变地图计算出现次数:
var bar = collection.mutable.Map[Int, Int]().withDefaultValue(0)
现在bar(a) += b 工作正常,无论bar 中是否已经存在密钥a(在这种情况下,它将被添加)。
我用可变映射的可变映射尝试了同样的事情:
var foo = collection.mutable.Map[Int, collection.mutable.Map[Int, Int]]().
withDefaultValue(collection.mutable.Map().withDefaultValue(0))
foo(a)(b) += x 在没有语法糖的情况下看起来如何?
使用 What are all the instances of syntactic sugar in Scala? 我会假设它扩展为:
foo.apply(a).put(b, foo.apply(a).apply(b) + x)
但是为什么这不会像介绍性示例中那样相应地更新 foo 本身(即,foo 将不会有一个专用值用于键 a,如果它以前不存在)?
编辑:作为Perseids pointed out,foo(a)(b) += x 将改变可变的默认值。这是一个理想的功能吗?
按照DaoWen 的建议使用getOrElseUpdate 似乎是克服这两个问题的最佳方法。但是,虽然这对于 Int => Int => Int 类型的函数很有效,但对于 Int => Int => Int => Int => Int 类型的函数来说确实很麻烦。所以我仍然很高兴有任何建议!
【问题讨论】:
-
foo(a)(在第一个示例中)和foo(a)(b)(在第二个示例中)都是 Int 类型。 Int class 中没有 += 方法。 -
完全正确,我处于 scala-daze 效果下!
-
"foo(a)(b) += x 将改变可变的默认值。这是一个理想的功能吗?" 我认为这是在设计时考虑到不可变对象.可以返回与默认值相同的不可变对象(例如,
Int或不可变的Map)。它不适用于可变值... -
真的有必要在地图中使用这么多层次的嵌套吗?您可以只使用元组作为键吗?换句话说,您将拥有
(Int, Int, Int, Int) => Int,而不是Int => Int => Int => Int => Int。