gpt4 book ai didi

scala - 不可变 val 与可变 ArrayBuffer

转载 作者:行者123 更新时间:2023-12-01 08:59:42 26 4
gpt4 key购买 nike

mutable vs. immutable in Scala collections

在我发布这个问题之前,我已经阅读了上面的文章。显然如果你在 val 中存储一些东西,你不能修改它,但是如果你存储一个可变集合,例如 ArrayBuffer,你可以修改它!

scala> val b = ArrayBuffer[Int](1,2,3)
b: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3)

scala> b += 1
res50: b.type = ArrayBuffer(1, 2, 3, 1)

scala> b
res51: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 1)

使用 val 存储可变的 ArrayBuffer 有什么用?我认为 b 更改的唯一原因是因为 val b 将内存地址保存到该 ArrayBuffer(1,2,3)

如果你尝试 var x = 1; val y = x; x = 5; y,输出仍然是 1。在这种情况下,y 存储一个实际值而不是 x 的地址。

Java 没有这种混淆,因为很明显不能将 Object 分配给 int 变量。

我如何知道 scala 中的变量何时携带值,何时是内存地址?将可变集合存储在不可变变量中有什么意义?

最佳答案

一个简单的答案是 vals 和 vars 都是引用。 Scala 中没有原始类型。它们都是对象。

val x = 1

是一个名为 x 的引用,它指向一个不可变的整数对象 1。你不能做 1.changeTo(2) 什么的,所以如果你有

val value = 5
val x = value
var y = value

您可以执行 y += 10 这将更改 y 以引用一个新对象,(5 + 10) = 15 。原来的 5 仍然是 5。

另一方面,您不能使用 x += 10,因为 x 是一个 val,这意味着它必须始终指向 5。所以,这不会编译。

你可能想知道为什么你可以先 val b = ArrayBuffer(...) 然后 b += something 即使 b 是一个瓦尔。那是因为 += 实际上是一个方法,而不是一个赋值。调用 b += something 会被翻译成 b.+=(something)。 += 方法只是将一个新元素(something)添加到其可变自身并返回自身以进行进一步分配。

我们来看一个例子

scala> val xs = ArrayBuffer(1,2,3)
xs: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3)

scala> val ys = ( xs += 999 )
ys: xs.type = ArrayBuffer(1, 2, 3, 999)

scala> xs
res0: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(1, 2, 3, 999)

scala> ys
res1: xs.type = ArrayBuffer(1, 2, 3, 999)

scala> xs eq ys
res2: Boolean = true

这确认 xsys 指向同一个(可变)ArrayBuffer。 eq 方法类似于Java 的==,比较对象的身份。可变/不可变引用(val/var)和可变/不可变数据结构(ArrayBuffer、List)是不同的。因此,如果您执行另一个 xs += 888,则作为指向可变数据结构的不可变引用的 ys 也包含 888

关于scala - 不可变 val 与可变 ArrayBuffer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20020468/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com