只为一个插槽增值

Adding value to only one slot

我正在尝试将值添加到数组中的单个槽。例如:

a = Array.new(3,[])    # => [[],[],[]]
a[1] << "value"        # => [[],["value"],[]]

但是,值会添加到数组中的所有槽中。

# => [["value"],["value"],["value"]]

这种行为有原因吗?是否有一种标准方法可以将值添加到数组以避免这种行为?

您看到此行为是因为新数组引用了同一个对象。您可以验证查看子数组的 object_ids:

a = Array.new(3, [])
p a[1] << "value"
p a[0].object_id
# => 70175034559160
p a[1].object_id
# => 70175034559160
p a[2].object_id
# => 70175034559160

你可以这样做:

a = []
(1..3).each { |e| a << [] }
a[1] << "value"
p a
# => [[], ["value"], []]

或者,使用这个更好:

a = Array.new(3) { Array.new }

如评论区@orde提供the documentation所示

您可以像这样初始化数组以确保每个元素都有自己的数组:

a = Array.new(3){ Array.new } # or a = Array.new(3){ [] }

而且,是的,正如另一个答案中所述,您之所以看到这一点,是因为在您初始化每个元素时,将同一个数组对象分配给它。您所做的与以下内容基本相同:

a1 = Array.new
a2 = Array.new(3, a1)

您添加值的方式没有任何问题。