为什么在二维数组中分配值时会有不同的结果?

时间:2015-01-10 06:31:57

标签: ruby arrays

这两项任务有什么区别?为什么他们有不同的结果?

arr3 = Array.new(2, Array.new(2, 0))
arr4 = [[0, 0], [0, 0]]

arr3 == arr4  # => true
arr3 === arr4  # => true

arr3[0][0] = "/"
arr4[0][0] = "/"

arr3  # => [["/", 0], ["/", 0]]
arr4  # => [["/", 0], [0, 0]]

2 个答案:

答案 0 :(得分:5)

因为arr3包含两个相同的对象,但arr4包含两个不同的对象。

>> arr3 = Array.new(2, Array.new(2, 0))
=> [[0, 0], [0, 0]]
>> arr3.map { |ary| ary.object_id }
=> [73703490, 73703490]
>> arr4 = [[0, 0], [0, 0]]
=> [[0, 0], [0, 0]]
>> arr4.map { |ary| ary.object_id }
=> [73670930, 73670920]
>>

阅读new(size=0, default=nil)

  

...在第一种形式中,如果没有发送参数,则新数组将为空。发送大小和可选默认值时,将创建一个包含默认大小副本的数组。 请注意,所有元素都会引用相同的对象默认

您使用上面的表单创建了arr3,同时使用文字构造函数arr4 创建[]

  

using the literal constructor []可以创建一个新数组。数组可以包含不同类型的对象。

如果您希望Array::new表现为文字构造,请使用new(size) {|index| block }形式。

>> arr3 = Array.new(2){ Array.new(2, 0) }
=> [[0, 0], [0, 0]]
>> arr3.map { |ary| ary.object_id }
=> [73551460, 73551450]
>>

答案 1 :(得分:-2)

arr3中的两个元素共享相同的object_id,因此它们将一起更改。

CODE:

arr3.each do |item|
  p item.object_id
end

arr4.each do |item|
  p item.object_id
end

但我仍然不知道为什么Array.new会发生这种情况。