`Array#<<` 是如何工作的?

How does `Array#<<` work?

假设我声明数组如下:

array1 = [1,2,3,4,5]
array2 = array1

两个数组的对象ID相同:

array1.object_id = 118945940
array2.object_id = 118945940

当我如下在数组中插入一个元素时,

array1 << 10

结果是

array1 = [1, 2, 3, 4, 5, 10]
array2 = [1, 2, 3, 4, 5, 10]

但是当我将新数组添加到数组 array1 时,

array1 = array1 + [11,12]

array1 = [1,2,3,4,5,10,11,12]
array2 = [1,2,3,4,5,10]

两个数组的对象 ID 都已更改。

<< 是如何工作的?

我认为这里的混淆是由于连接两个数组实际上创建了一个新数组(即:一个新对象)。

array1 + array2

这将创建一个包含两个数组内容的新数组。所以对象id会改变,因为它是一个不同的对象。

当您使用 << 运算符时,它只是向数组添加一个元素 - ruby 不会创建新对象,因此两个数组(共享一个对象 ID)都会获得新的元素。

array 是一个变量,包含对实际数组(class Array 的实例)的引用(指针、句柄、ID - 无论您想要调用它)。

array (variable)   -------------------> object (instance of class Array)

你的代码是做什么的?让我们看看:

array << value

这与调用方法完全相同:array.append(value)。没有创建 Array 的新实例。您没有为变量 array 分配新值。实际的数组对象当然在变化,但它的引用没有变化。

array1 = array1 + array2

右边的赋值,array1 + array2,必须创建一个新的Array实例。这很容易看出——代码直觉上不应该修改 array1array2。然后将对该新数组的引用存储在变量 array1.