当我们可以添加或删除元素时,Map 或 List 怎么可能是不可变的呢?

How can a Map or List be immutable when we can add or remove elements from them?

下面是声明不可变映射的 Scala 代码

var m:Map[Int,String] = Map(1->"hi",2->"hello")
println(m)
// Result: Map(1->"hi",2->"hello")

这里我们可以添加或更改Map的内容,那我们怎么能说scala中的map或list是不可变的呢

m=m+(3->"hey") 
println(m)
// Result: Map(1->"hi",2->"hello",3->"hey")**

Map 是不可变的,但是您使用了 mutable 变量 m(因为您将其声明为 var)。

这一行 m=m+(3->"hey") 实际上创建了一个新地图并将其分配给您的变量 m

尝试将 m 声明为 val,您会发现编译错误。

但是 - 如果您将使用可变映射:

val m = scala.collection.mutable.Map[Int,String]

您将能够更新此地图(但您不能使用不可变地图执行此操作)-

m(3) = "hey"

m.put(3,"hey")

这就是您更新地图内容的方式,无需重新创建它或更改变量 m(就像您之前使用 m = m + ... 所做的那样),因为此处 m 是声明为 val,这使其不可变,但映射是可变的。

当声明为 val 时,您仍然不能执行 m = m + ..

varval的区别请参考这篇answer

即使您认为您的问题与 varval 无关,但实际上是:在您的示例中,m 是否定义为 [=11] 非常重要=] 或 val。在您的示例中,即使您看到地图已更改,但实际上并没有:您的代码创建了 另一个 地图并将其分配给同一个变量。地图本身没有改变,因为它是不可变的。您可以在这段代码中观察到这一点:

val m1 = Map(1 -> "hi", 2 -> "hello")

var m = m1
m = m + (3 -> "hey")

println(m)   // prints Map(1 -> ..., 2 -> ..., 3 -> ...)
println(m1)  // prints Map(1 -> ..., 2 -> ...)

如果 Map 在这里是可变的,您会看到 m1 也发生了变化。因为你没有看到这个,这意味着地图是不可变的,只有变量是。