Ruby 一个关于 Ruby 数组初始化的问题

cassiuschen · 2015年11月08日 · 最后由 dandananddada 回复于 2015年11月09日 · 2521 次阅读

在写一段代码,其中一个片段是要初始化一个形如:

| 0 | 1 | 2 | 3 | 4 |
| 1 | 0 | 0 | 0 | 0 |
| 2 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 0 | 0 |

的二维数组,于是我用了以下非常难看的代码实现:

dif = Array.new(row_length, Array.new(column_length, 0))

(0...row_length).each do |i|
  dif[i][0] = i
end #mark1

(0...column_length).each do |i|
  dif[0][i] = i
end

结果生成了:

| 0 | 1 | 2 | 3 | 4 |
| 0 | 1 | 2 | 3 | 4 |
| 0 | 1 | 2 | 3 | 4 |
| 0 | 1 | 2 | 3 | 4 |

不得其解,于是打断点看数据,发现在mark1处数据被写成了:

| 3 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 0 | 0 |
| 3 | 0 | 0 | 0 | 0 |

于是便想到会不会是这里这个循环中i的实例化过程并不和我所想的,每次循环时下面语句被重新改写……这个问题是不是在编译过程当中产生的? 经过 @luikore 和身边的 @chunlea 提点,查了下文档,发现: Array.new(size, default)方法中这个default在填充数组的时候共用object_id,即为同一个对象,因此对其赋值要有一定的觉悟……

因为改的同一个引用...

Array.new row_length do
   Array.new column_length, 0
end

#1 楼 @luikore 能稍微详细一点么>~<

#1 楼 @luikore 哦明白了……原来是文档读的不精……

@cassiuschen

Array.new(4) {|i| Array.new(5) {|j| i*j==0 ? i+j : 0 } }
#=> => [[0, 1, 2, 3, 4], [1, 0, 0, 0, 0], [2, 0, 0, 0, 0], [3, 0, 0, 0, 0]]
需要 登录 后方可回复, 如果你还没有账号请 注册新账号