Scala 带DefaultValue的嵌套映射更改默认值

Scala 带DefaultValue的嵌套映射更改默认值,scala,map,default-value,mutable,Scala,Map,Default Value,Mutable,我有一个包含另一个可变映射的可变映射,这两个都是默认值。将值指定给封闭贴图中的一个键后,其默认值似乎会更改。 例如,我希望另一个默认值具有值映射(1->default),而不是映射(1->something) 为什么会这样 scala> import scala.collection.mutable.{Map => MMap} import scala.collection.mutable.{Map=>MMap} scala> val amap = Map[Int, M

我有一个包含另一个可变映射的可变映射,这两个都是默认值。将值指定给封闭贴图中的一个键后,其默认值似乎会更改。 例如,我希望另一个默认值具有值映射(1->default),而不是映射(1->something)

为什么会这样

scala> import scala.collection.mutable.{Map => MMap}
import scala.collection.mutable.{Map=>MMap}

scala> val amap = Map[Int, MMap[Int, String]]().withDefaultValue(MMap().withDefaultValue("default"))
amap: scala.collection.immutable.Map[Int,scala.collection.mutable.Map[Int,String]] = Map()

scala> val bmap = amap(2)
bmap: scala.collection.mutable.Map[Int,String] = Map()

scala> bmap(1)
res17: String = default

scala> bmap(1) = "something"

scala> val anotherDefault = amap(3)
anotherDefault: scala.collection.mutable.Map[Int,String] = Map(1 -> something)
外部映射(
amap
)正在创建内部映射的单个实例以用作默认值。当您通过
val bmap=amap(2)
访问此映射,然后修改
bmap
时,您正在修改
amap
使用的单个默认映射。当您调用
amap(3)
时,您将返回此默认映射,它现在是一个具有键/值对
(1->“某物”)
的映射

您可能想要的是使用默认值的
,而不是使用默认值的
,尽管它需要一些额外的参数/类型规范才能工作:

val amap = Map[Int, MMap[Int, String]]().withDefault(x => MMap[Int, String]().withDefaultValue("default"))
外部映射(
amap
)正在创建内部映射的单个实例以用作默认值。当您通过
val bmap=amap(2)
访问此映射,然后修改
bmap
时,您正在修改
amap
使用的单个默认映射。当您调用
amap(3)
时,您将返回此默认映射,它现在是一个具有键/值对
(1->“某物”)
的映射

您可能想要的是使用默认值的
,而不是使用默认值的
,尽管它需要一些额外的参数/类型规范才能工作:

val amap = Map[Int, MMap[Int, String]]().withDefault(x => MMap[Int, String]().withDefaultValue("default"))

如果是这种情况,这意味着可变映射上的withDefaultValue()是无用的,甚至是误导性的?一点也不-
bmap(4)
仍将生成值“default”,而不是抛出NosTouchElementException。因此,defaultValue不是不可变的,我们可以在不知情的情况下更改默认值。这有点出乎意料。非常感谢withDefault()的澄清!您提供的默认值不是不可变的,因为您提供了一个可变映射。如果您提供了一个不可变的映射,那么您的默认值确实是不可变的。如果是这种情况,这意味着可变映射上的withDefaultValue()是无用的,甚至是误导性的?一点也不-
bmap(4)
仍将产生值“default”,而不是抛出一个NoTouchElementException。因此,默认值不是不可变的,我们可以在不知情的情况下更改默认值。这有点出乎意料。非常感谢withDefault()的澄清!您提供的默认值不是不可变的,因为您提供了一个可变映射。如果您提供了一个不可变的映射,那么您的默认值确实是不可变的。