遅い答えですが、Web(または少なくとも通常のソース)で十分なカバレッジが得られない言語設計の非常に重要な側面です。
x <- c(0,4,2)
lobstr::obj_addr(x)
# [1] "0x7ff25e82b0f8"
y <- x
lobstr::obj_addr(y)
# [1] "0x7ff25e82b0f8"
同一の「メモリアドレス」、つまりオブジェクトが保存されているメモリ内の場所に注意してください。したがって、それを確認しx
、y
両方が同じ識別子を指していることを確認できます。
ハドリーウィッカムのアドバンストRの本はこれに触れています:
このコードを検討してください:
x <- c(1, 2, 3)
「値1、2、および3を含む「x」という名前のオブジェクトを作成する」と読みやすくなります。残念ながら、これは単純化されたものであり、Rが実際に舞台裏で行っていることについての不正確な予測につながります。このコードは2つのことを行っていると言った方が正確です。
オブジェクト、値のベクトル、を作成していますc(1, 2, 3)
。そして、そのオブジェクトを名前にバインドしますx
。つまり、オブジェクトまたは値には名前がありません。実際には、値を持つ名前です。
これらはメモリアドレスであり、一時的なものであり、新しいRセッションごとに変更されることに注意してください。
ここが重要な部分です。
Rセマンティクスでは、オブジェクトは値によってコピーされます。これは、コピーを変更すると、元のオブジェクトがそのまま残ることを意味します。メモリ内のデータのコピーはコストのかかる操作であるため、R内のコピーは可能な限り遅延します。これらは、新しいオブジェクトが実際に変更されたときにのみ発生します。出典:[Rlangドキュメント][1]
したがってy
、ベクトルに値を追加しての値を変更するy
と、は別の「オブジェクト」を指すようになります。これは、「新しいオブジェクトが変更された場合にのみ」(遅延)発生するコピー操作に関してドキュメントに記載されている内容と一致します。y
以前とは異なるアドレスを指しています。
y <- c(y, -3)
print(lobstr::obj_addr(y))
# [1] "0x7ff25e825b48"