【问题标题】:Immutable maps within Mutable maps support Mutable operations可变映射中的不可变映射支持可变操作
【发布时间】:2015-11-04 22:55:49
【问题描述】:

我今天正在编写一些代码时注意到了这种古怪的行为。嵌套在可变映射中的不可变映射似乎允许(通常是可变的)+= 运算符。

scala> val myMutableMap = mutable.Map[String, scala.collection.immutable.Map[String, String]]()
myMutableMap: scala.collection.mutable.Map[String,scala.collection.immutable.Map[String,String]] = Map()

scala> myMutableMap += "outerkey" -> scala.collection.immutable.Map("k1"-> "v1")
res25: myMutableMap.type = Map(outerkey -> Map(k1 -> v1))

scala> myMutableMap("outerkey") += "k2"->"v2"

scala> myMutableMap
res27: scala.collection.mutable.Map[String,scala.collection.immutable.Map[String,String]] = Map(outerkey -> Map(k1 -> v1, k2 -> v2))

scala> val huhwhat = myMutableMap("outerkey")
huhwhat: scala.collection.immutable.Map[String,String] = Map(k1 -> v1, k2 -> v2)

scala> huhwhat += "k3"->"k4"
<console>:21: error: value += is not a member of scala.collection.immutable.Map[String,String]
              huhwhat += "k3"->"k4"

我查看了 Map.scala 源代码,但没有看到任何关于 += 运算符可以从何处继承的明显答案。

这是在 Scala 2.11.5 上的。有谁知道怎么回事?

【问题讨论】:

    标签: scala


    【解决方案1】:
    myMutableMap("outerkey") += "k2"->"v2"
    

    被编译器解释为

    myMutableMap("outerkey") = myMutableMap("outerkey") + ("k2"->"v2")
    

    即,使用添加的密钥 ("k2"-&gt;"v2") 从不可变的 myMutableMap("outerkey") 创建一个新映射,并使用新的对 ("outerkey" -&gt; &lt;the new map&gt;) 更新 myMutableMap

    这是由mutable.MapLikeupdate method 实现的,它提供foo(x) = y 行为。有关更多信息,请参阅 this blog post(还有一个 SO 答案列表 a bunch of other magic functions in Scala)。

    【讨论】:

    • 更准确地说:如果 Scala 没有找到合适的 += (或 -= ...)方法,它将再次使用 foo = foo + bar 重试并使用它,如果它进行类型检查. foo(bar) = baz,然后又被解释为foo.update(bar, baz),它基本上是apply 的“setter”等价物。
    猜你喜欢
    • 1970-01-01
    • 2017-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-20
    • 1970-01-01
    • 2023-04-09
    相关资源
    最近更新 更多