“val”或“var”,可变还是不可变?
我可以定义一个不可变的变量(通过 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< 的成员/code>,那么发生了什么?
I can define a variable (by var
) that is immutable:
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]])
This results in:
true
true
+=
method is not a member of scala.collection.immutable.Set
, so what is happening?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
编译器会查找
x.+= ...
,如果找不到,则会尝试将语句转换为x = x + ...
(只有当x
是var
或x
脱糖到对某些update
方法的调用时才会成功)。由于immutable.Set
实现了+
运算符,并且x
是var
,因此成功。The compiler looks for
x.+= ...
, and if it can't find it, then it tries to transform the statement intox = x + ...
(which only succeeds ifx
is avar
, orx
desugars into a call to someupdate
method). Sinceimmutable.Set
implements a+
operator, andx
is avar
, this succeeds.原来的不可变集仍然没有改变。
继续Ken的回答,+创建了一个新集合,附加新项目,并返回新集合,保持原始集合对象不变。所以你可以说 var y = x; y += "cccc" 并且您将拥有 2 个集合而不是 1 个:
获取:
您会看到数据结构本身仍然是不可变的,但因为您声明了
var
,所以赋值是可变的。因此,如果返回的话,它可以重新指向一个新对象。如果您更改为将x
声明为val
,则无法将其重新分配给新地址。如果您使用了 mutable 集,则
x
和y
将指向同一个对象,因为+
调用会追加现有的集合而不是返回一个新的集合(可变...):获取:
瞧。
The original immutable set is still unchanged.
Continuing Ken's answer, the + has created a new set, appended the new item, and returned the new set, leaving the original set object unchanged. So you could say
var y = x; y += "cccc"
and you would have 2 sets instead of 1:Getting:
You see the data structure itself is still immutable, but because you declared a
var
, the assignment is mutable. So it can be repointed to a new object if that is returned. If you change to declaringx
as aval
, then you couldn't reassign it to a new address.If you had used a mutable set, then
x
andy
would point to the same object because the+
call would have appended the existing set rather than returning a new one (being mutable...):Get:
Voila.