我可以定义一个不可变的变量(var
):
var x = scala.collection.immutable.Set("aaaaaa","bbbbbb")
println(x.isInstanceOf[scala.collection.immutable.Set[String]])
x += "cccc"
println(x.isInstanceOf[scala.collection.immutable.Set[String]])
这导致:
true
true
+=
方法不是scala.collection.immutable.Set
的成员,那么发生了什么?
答案 0 :(得分:22)
编译器查找x.+= ...
,如果找不到它,则会尝试将语句转换为x = x + ...
(仅当x
为{{1}时才会成功}},或var
desugars调用某些x
方法)。由于update
实现了immutable.Set
运算符,而+
是x
,因此成功。
答案 1 :(得分:6)
原始的不可变集合仍未改变。
继续Ken's answer,+已创建一个新集,附加新项,并返回新集,保持原始集对象不变。所以你可以说var y = x; y += "cccc"
而你会有2套而不是1:
var x = scala.collection.immutable.Set("aaaaaa","bbbbbb")
println(x.isInstanceOf[scala.collection.immutable.Set[String]])
var y = x
y += "cccc"
println(x)
println(y)
println(x.isInstanceOf[scala.collection.immutable.Set[String]])
println(y.isInstanceOf[scala.collection.immutable.Set[String]])
获得:
> true
> Set(aaaaaa, bbbbbb)
> Set(aaaaaa, bbbbbb, cccc)
> true
> true
您看到数据结构本身仍然是不可变的,但由于您声明了var
,因此赋值是可变的。因此,如果返回它,它可以被重新命名为新对象。如果您更改为将x
声明为val
,则无法将其重新分配给新地址。
如果您使用了可变集,则x
和y
会指向同一个对象,因为+
调用会附加现有集合而不是返回一个新的(可变......):
var x = scala.collection.mutable.Set("aaaaaa","bbbbbb")
println(x.isInstanceOf[scala.collection.immutable.Set[String]])
var y = x
y += "cccc"
println(x)
println(y)
得到:
> Set("aaaaaa","bbbbbb","cccc")
> Set("aaaaaa","bbbbbb","cccc")
瞧。