今天想生成一个二维数组,突然突发奇想想出了这个方法 matrix = [[0] * 5] * 10
,然后发生奇迹的事情了。
[1] pry(main)> matrix = [[0] * 5] * 10
=> [[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], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
[2] pry(main)> matrix[1][1] = 2
=> 2
[3] pry(main)> matrix
=> [[0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0], [0, 2, 0, 0, 0]]
你会发现每一行的数组其实都是在被复制的,你改动任何一行的数据,其他几行的数据就会一起被改动。
查看 C 源码后发现都是 memcpy 在作祟
ary_memcpy(ary2, 0, t, ptr);
while (t <= len/2) {
ary_memcpy(ary2, t, t, RARRAY_CONST_PTR(ary2));
t *= 2;
}
if (t < len) {
ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR(ary2));
}
正确方法应该是 matrix = Array.new(10) {Array.new(5, init_value)}