当我们可以在地图或列表中添加或删除元素时,它们如何不可变?

时间:2019-07-08 06:02:30

标签: scala immutable-collections

下面是声明不可变Map的scala代码

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

在这里我们能够添加或更改Map的内容,那么我们如何说Scala中的地图或列表是不可变的

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

2 个答案:

答案 0 :(得分:8)

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,使其不可变,但地图是可变的。

m = m + ..声明为val时,您仍然无法执行操作。

有关varval之间的区别,请参考此answer

答案 1 :(得分:2)

即使您认为您的问题与varval无关,实际上也是如此:在您的示例中,将m定义为var非常重要或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也已更改。因为您看不到它,所以它意味着该映射不是可变的,只有变量是可变的。