gpt4 book ai didi

Scala 赋值与引用类型

转载 作者:行者123 更新时间:2023-12-02 17:45:07 26 4
gpt4 key购买 nike

我以为我已经牢牢掌握了 Scala 对引用类型(即从 AnyRef 派生的那些)的处理方式,但现在我不太确定。

如果我像这样创建一个简单的类

class C(var x: Int = 0) {}

并定义几个实例

var a = new C
var b = new C(1)
var c = new C(2)

然后我分配

a = b

我没有得到(浅)副本,而是对 a 实例的原始引用永远丢失了,a 和 b 本质上是同一对象的“别名”。 (通过查看这些项目的地址可以看出这一点。)这很好,很明智。同样清楚的是,这些是引用(而不是值),因为我可以做到

c = null

这不会产生错误。

现在,假设我这样做

import scala.math.BigInt
var x = BigInt("12345678987654321")
var y = BigInt("98765432123456789")
var z = x + y

这将创建三个 BigInts,其中包含 x、y 和 z,我想是对它们的引用。其实我可以的

z = null

再次没有错误。然而,

y = x
x += 1

不会导致 y 改变,也就是说,在这种情况下,赋值似乎并没有简单地为 x 引用的对象创建另一个“名称”,而是复制了它。

为什么会这样?我找不到任何机制(例如,类似于 C++ 的“复制构造函数”)会被(看起来是)直接引用赋值静默调用。

任何解释将不胜感激,因为两天的网络搜索已证明无果。

最佳答案

x += 1 will be expanded into x = x + 1 所以它不仅仅是赋值。

如果您查看 bigInt 的源代码,您会看到 + 创建了新实例:

def +  (that: BigInt): BigInt = new BigInt(this.bigInteger.add(that.bigInteger))

事实上,它使用了 java 的 BigInteger,其添加操作使两个参数保持不变。

所以最终基本上发生的是对不可变加法的复制构造函数结果的引用重新分配

关于Scala 赋值与引用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15959615/

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