为什么val x = mutable.Map(...)在scala中是可变的?

时间:2017-06-10 09:06:53

标签: scala

考虑以下示例

案例1:

>scala val x = 1
 x:Int = 1
>scala x = 2
<console>:11: error: reassignment to val
   x=2
    ^

案例2:

scala> val name = new scala.collection.mutable.HashMap[String, Int]
name: scala.collection.mutable.HashMap[String,Int] = Map()

scala>name("Hello") = 1
scala>name
res1: scala.collection.mutable.HashMap[String,Int] = Map(Hello -> 1)

我可以理解案例1,因为x是val - 类型。对于案例2,虽然name也是val - 类型,但name是可变的。怎么解释呢?

4 个答案:

答案 0 :(得分:3)

无论您使用mutable.HashMap还是val

var都是可变的。

val如果您正在变更/重新分配实例的引用,则会有所不同,因为val不允许重新分配但var会重新分配。

例如

允许变异数据,

scala> val mutableMap = new scala.collection.mutable.HashMap[String, Int]
mutableMap: scala.collection.mutable.HashMap[String,Int] = Map()

scala> mutableMap += ("some name" -> 8888)
res3: mutableMap.type = Map(some name -> 8888)

但由于val

,因此不允许变更引用
scala> mutableMap = new scala.collection.mutable.HashMap[String, Int]
<console>:12: error: reassignment to val
       mutableMap = new scala.collection.mutable.HashMap[String, Int]
                  ^

如果您想要不可变地图(无数据变异),请使用scala.collection.Map

scala> val immutableMap = scala.collection.Map("prayagupd" -> 1000)
immutableMap: scala.collection.Map[String,Int] = Map(prayagupd -> 1000)

答案 1 :(得分:2)

在第二种情况下,名称是指向ngClass的{​​{1}},而您正在编辑pointer

mutable.HashMap

您已明确将hashMap定义为name("Hello") = 1 ,这就是您可以编辑它的原因。但是,您无法hashmap与另一个mutable reference

相同的object
name

但如果您将name = new scala.collection.mutable.HashMap[String, Int] 定义为

var

您可var name = new scala.collection.mutable.HashMap[String, Int] 与任何其他reference/point

答案 2 :(得分:1)

  

阶&GT; val name = new scala.collection.mutable.HashMap [String,Int]

这里reference是可变的,Map集合不是,你可以添加/删除该地图中的元素mutable.HashMap类型,如果你想要不可变版本试试默认Scala Map

Qutoting了解更多详情:http://docs.scala-lang.org/overviews/collections/overview.html

  

Scala集合系统地区分可变集合和不可变集合。可以更新或扩展可变集合。这意味着您可以更改,添加或删除集合的元素作为副作用。相比之下,不变的收藏品永远不会改变。您仍然有模拟添加,删除或更新的操作,但这些操作将在每种情况下返回一个新集合并保持旧集合不变。

答案 3 :(得分:1)

在您的示例中,val名称是对可变实例的不可变引用。您明确请求一个hashmap是可变的。名称引用是val而不是var因为你不能覆盖引用,并且总是指向同一个对象,尽管对象可能会改变。

您可以创建对不可变映射的var引用以创建相反的影响。