1

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

これにより、x、y、z を持つ 3 つの BigInts が作成されます。これは、これらへの参照と思われます。実際、私はできる

z = null

また、エラーは発生しません。でも、

y = x
x += 1

は y を変更しませ。つまり、この場合、代入は単に x によって参照されるオブジェクトの別の「名前」を作成したのではなく、そのコピーを作成したように見えます。

なぜこれが起こるのですか?単純な参照割り当て (と思われるもの) によってサイレントに呼び出されるメカニズム (たとえば、C++ の「コピー コンストラクター」に似たもの) を見つけることができません。

2 日間の Web 検索が実を結ばなかったので、どんな説明でも大歓迎です。

4

3 に答える 3

5

x += 1 に拡張される x = x + 1ので、割り当てだけではありません。

bigInt のソースを見ると、 + が新しいインスタンスを作成することがわかります。

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

実際、追加操作で両方の引数をそのままにしておくJavaのBigIntegerを使用しています。

したがって、基本的に一日の終わりに起こるのは、不変の追加のコピー コンストラクターの結果の参照の再割り当てです。

于 2013-04-11T22:06:05.430 に答える
1
y = x
x += 1  

BigInt は不変であるため、+1 は新しい BigInt を作成するため、y は変更されません。新しい BigInt オブジェクトyを指している間、まだ前のオブジェクトを指しています。x

于 2013-04-11T22:05:53.457 に答える