Scala 当我们可以从映射或列表中添加或删除元素时,映射或列表如何是不可变的?

Scala 当我们可以从映射或列表中添加或删除元素时,映射或列表如何是不可变的?,scala,immutable-collections,Scala,Immutable Collections,下面是声明不可变映射的scala代码 var m:Map[Int,String] = Map(1->"hi",2->"hello") println(m) // Result: Map(1->"hi",2->"hello") 在这里,我们可以添加或更改映射的内容,那么如何说scala中的映射或列表是不可变的呢 m=m+(3->"hey") println(m) // Result: Map(1->"hi",2->"hello",3->"hey"

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

var m:Map[Int,String] = Map(1->"hi",2->"hello")
println(m)
// Result: Map(1->"hi",2->"hello")
在这里,我们可以添加或更改映射的内容,那么如何说scala中的映射或列表是不可变的呢

m=m+(3->"hey") 
println(m)
// Result: Map(1->"hi",2->"hello",3->"hey")**
Map是不可变的,但您使用了可变变量m,因为您将其声明为var

这行m=m+3->hey实际上创建了一个新映射,并将其分配给变量m

尝试将m声明为val,并查看是否会出现编译错误

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

val m = scala.collection.mutable.Map[Int,String]
您将能够更新此映射,但无法使用不可变映射执行此操作-

m(3) = "hey"

这就是更新映射内容的方式,而无需重新创建映射或更改变量m,就像之前使用m=m+…,因为这里m被声明为val,这使得它是不可变的,但映射是可变的

你仍然不能做m=m+。。当它被声明为val时

关于var和val之间的差异,请参阅此部分。

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

这行m=m+3->hey实际上创建了一个新映射,并将其分配给变量m

尝试将m声明为val,并查看是否会出现编译错误

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

val m = scala.collection.mutable.Map[Int,String]
您将能够更新此映射,但无法使用不可变映射执行此操作-

m(3) = "hey"

这就是更新映射内容的方式,而无需重新创建映射或更改变量m,就像之前使用m=m+…,因为这里m被声明为val,这使得它是不可变的,但映射是可变的

你仍然不能做m=m+。。当它被声明为val时


关于var和val之间的差异,请参考此部分。

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

val m1=Map1->hi,2->hello var m=m1 m=m+3->hey printlnm//打印地图1->,2->,3->。。。 printlnm1//打印地图1->…,2->。。。
若Map在这里是可变的,你们会看到m1也发生了变化。因为你看不到这一点,这意味着映射是不可变的,只有变量是可变的。

即使你认为你的问题不是关于var或val,实际上是:在你的例子中,m是定义为var还是val是非常重要的。在你的例子中,即使你看到映射发生了变化,它实际上没有:您的代码创建另一个映射并将其分配给同一个变量。地图本身没有改变,因为它是不可变的。您可以在以下代码中观察到这一点:

val m1=Map1->hi,2->hello var m=m1 m=m+3->hey printlnm//打印地图1->,2->,3->。。。 printlnm1//打印地图1->…,2->。。。
若Map在这里是可变的,你们会看到m1也发生了变化。因为您看不到这一点,这意味着映射是不可变的,只有变量是可变的。

任何声明为Val的内容都是不可变的。即使你像下面这样声明一个可变映射,它也是不可变的val m=scala.collection.Mutable.Map1->hi,2->helloMy问题不是关于val和Var,而是关于scala映射/列表的不可变性。Scala doc说映射是不可变的。更新我的答案-无论如何,如果你想保持变量不可变,最好避免使用var。当然,除非您再次使用可变集合更新我的答案,否则我希望现在答案更清楚。@AbhinavKumar您的第一个评论是错误的;可变。映射即使分配给val也是可变的。任何声明为val的内容都是不可变的。即使你像下面这样声明一个可变映射,它也是不可变的val m=scala.collection.Mutable.Map1->hi,2->helloMy问题不是关于val和Var,而是关于scala映射/列表的不可变性。Scala doc说映射是不可变的。更新我的答案-无论如何,如果你想保持变量不可变,最好避免使用var。当然,除非您再次使用可变集合更新我的答案,否则我希望现在答案更清楚。@AbhinavKumar您的第一个评论是错误的;可变。即使分配给val,Map也是可变的。当您更改M=M+3->hey时,为什么M1会在这里更改。请验证您的答案一次。@AbhinavKumar因为就在var m=m1之后,m和m1都指向同一数据。@AbhinavKumar这就是点,实际上-m1不会改变。如果Map是可变的,并且m=m+。。。改变了m,那么因为m1和m在改变点之前指向同一个对象,你会看到m1也改变了。这并没有发生,这意味着Map是不可变的。当你们改变了M=M+3->hey,为什么M1会在这里改变呢。请验证您的答案一次。@AbhinavKumar因为您的答案正确
er var m=m1 m和m1都指向相同的数据。@AbhinavKumar这就是点,实际上-m1不会改变。如果Map是可变的,并且m=m+。。。改变了m,那么因为m1和m在改变点之前指向同一个对象,你会看到m1也改变了。它不会发生,这意味着Map是不可变的。