“val”或“var”,可变还是不可变?

发布于 2024-10-18 12:28:03 字数 416 浏览 1 评论 0原文

我可以定义一个不可变的变量(通过 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

伪装你 2024-10-25 12:28:03

编译器会查找 x.+= ...,如果找不到,则会尝试将语句转换为 x = x + ... (只有当 xvarx 脱糖到对某些 update 方法的调用时才会成功)。由于 immutable.Set 实现了 + 运算符,并且 xvar,因此成功。

The compiler looks for x.+= ..., and if it can't find it, then it tries to transform the statement into x = x + ... (which only succeeds if x is a var, or x desugars into a call to some update method). Since immutable.Set implements a + operator, and x is a var, this succeeds.

遮云壑 2024-10-25 12:28:03

原来的不可变集仍然没有改变。

继续Ken的回答,+创建了一个新集合,附加新项目,并返回新集合,保持原始集合对象不变。所以你可以说 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,则无法将其重新分配给新地址。

如果您使用了 mutable 集,则 xy 将指向同一个对象,因为 + 调用会追加现有的集合而不是返回一个新的集合(可变...):

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")

瞧。

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:

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]])

Getting:

> true
> Set(aaaaaa, bbbbbb)
> Set(aaaaaa, bbbbbb, cccc)
> true
> true

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 declaring x as a val, then you couldn't reassign it to a new address.

If you had used a mutable set, then x and y would point to the same object because the + call would have appended the existing set rather than returning a new one (being mutable...):

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)

Get:

> Set("aaaaaa","bbbbbb","cccc")
> Set("aaaaaa","bbbbbb","cccc")

Voila.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文