我正在创建一个嵌套数组,以两种不同的方式存储一些字母。第一种方式是:
Array.new(rows, Array.new(columns){ O })
第二种方式是:
Array.new(rows) do
Array.new(columns) { O }
end
他们看起来完全一样:
[["0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0"]]
当我想用另一个字母替换一个位置并执行:
array[1][3] = R
以第一种方式生成数组,整个第一列将变为R
。使用第二种方式,只会将位置[1][3]
替换为包含R
。
我想知道两种方式之间的区别是什么。
答案 0 :(得分:6)
在第一个示例中:Array.new(rows, Array.new(columns){ O })
,第二个参数指定数组的默认值作为对象引用。换句话说,在第一个示例中,您指定对每一行使用相同的确切对象,而在第二个块版本中,该表达式针对每一行单独计算,为您提供可以独立更改的唯一对象。 / p>
见这里:http://ruby-doc.org/core-2.2.0/Array.html#method-c-new-label-Common+gotchas
取自以上链接:
发送第二个参数时,将使用相同的对象作为 所有数组元素的值:
a = Array.new(2, Hash.new) # => [{}, {}] a[0]['cat'] = 'feline' a # => [{"cat"=>"feline"}, {"cat"=>"feline"}] a[1]['cat'] = 'Felix' a # => [{"cat"=>"Felix"}, {"cat"=>"Felix"}]
由于所有Array元素都存储相同的哈希值,因此更改为其中一个哈希值 他们会影响他们。
如果您想要多个副本,则应使用块版本 每次使用数组的一个元素时,它会使用该块的结果 需要初始化:
a = Array.new(2) { Hash.new } a[0]['cat'] = 'feline' a # => [{"cat"=>"feline"}, {}]