2013-10-01 4 views
1

У меня есть изменяемая карта, содержащая другую изменчивую карту, как со значениями по умолчанию. После того, как я присвою значение одному ключу на прилагаемой карте, его значение по умолчанию, похоже, изменится. I.e. Я ожидал, что anotherDefault будет иметь значение Map (1 -> default), NOT Map (1 -> something).Вложенная карта withDefaultValue меняет значение по умолчанию

Почему это происходит?

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) 

ответ

4

Внешняя карта (amap) создает один экземпляр внутренней карты для использования в качестве значения по умолчанию. Когда вы получаете доступ к этому через val bmap = amap(2), затем изменяйте bmap, вы изменяете единую карту по умолчанию, используемую amap. Когда вы вызываете amap(3), вы затем возвращаете эту карту по умолчанию, которая теперь представляет собой карту с парой ключ/значение (1 -> "something").

То, что вы, вероятно, хотите, withDefault, не withDefaultValue, хотя и нуждается в некоторых дополнительных спецификациях аргумента/типа работы:

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

Если это так, то это означает, что withDefaultValue() на изменяемую карте бесполезно , или даже ввести в заблуждение? – Adrian

+0

Совсем нет - 'bmap (4)' будет по-прежнему выдавать значение «default», а не бросать исключение NoSuchElementException. – Shadowlands

+0

Таким образом, значение defaultValue не является неизменным, и мы можем неосознанно изменять значение по умолчанию. Это несколько неожиданно. – Adrian