ruby 中连接类型的区别

Difference between concatenation types in ruby

我正在尝试编写自己的转置方法。我想知道不同形式的串联如何影响我的代码。

multi = [[1,3,5],[2,4,6],[7,9,8]]
new = Array.new(multi.length, [])
multi.each do |c|
    c.each_with_index do |x,y|
        new[y] += [x]
    end
end
new #=> [[1, 3, 5], [2, 4, 6], [7, 9, 8]]

multi = [[1,3,5],[2,4,6],[7,9,8]]
new = Array.new(multi.length, [])
multi.each do |c|
    c.each_with_index do |x,y|
        new[y] << x
    end
end
new #=> [[1, 3, 5, 2, 4, 6, 7, 9, 8], [1, 3, 5, 2, 4, 6, 7, 9, 8], [1, 3, 5, 2, 4, 6, 7, 9, 8]]

为什么它们的工作方式不同?

new = Array.new(multi.length, [])
# => [[], [], []]

new 中的元素引用相同的 Array 对象。查看他们的 ID:

new.map {|e| e.object_id}
# => [1625920, 1625920, 1625920]

第一个代码片段给了你预期的结果,因为 new[y] += [x] 分配给 new[y] 一个新的 Array 对象,所以 new 中的每个元素现在都没有引用到同一个对象:

new.map {|e| e.object_id}
# => [22798480, 22798440, 22798400]

对于第二个代码片段,new 中的每个元素仍然引用原始 Array 对象。