为何修改Ruby二维数组单个元素时多行对应位置值均变更?
Ruby二维数组初始化的引用陷阱解析
你遇到的问题核心是数组引用的共享,具体原因如下:
问题根源:[[false]*4] * 3的本质
[false]*4确实会创建一个包含4个false的数组,但后续的*3操作并没有生成3个独立的该数组副本,而是将同一个数组对象的引用重复添加到外层数组中。也就是说,visited的三个元素指向的是内存中同一个数组实例——看起来是三行,实则是同一个数组被引用了三次。
所以当你执行visited[1][2] = 1时,本质是修改了那个唯一的底层数组的第3个元素(索引2),所有指向它的"行"自然都会显示这个修改结果。
补充:和Python的异同
其实Python中使用[[False]*4]*3初始化二维数组时,也会出现完全相同的问题。你之前在Python中没有遇到,大概率是用了正确的初始化方式(比如列表推导式[[False for _ in range(4)] for _ in range(3)]),这种方式会为每一行创建独立的数组对象。
正确的二维数组初始化方式
要避免引用共享,需要确保每一行都是独立的数组对象,推荐两种写法:
- 使用
Array.new的块初始化:
visited = Array.new(3) { [false] * 4 }
这里Array.new(3) { ... }会为外层数组的每个元素单独执行块内代码,每次生成一个新的[false]*4数组,确保三行互相独立。
- 手动逐行初始化:
visited = [ [false, false, false, false], [false, false, false, false], [false, false, false, false] ]
这种方式直观地创建三个独立的数组,自然不会有引用共享问题。
用以上方式初始化后,执行visited[1][2] = 1,就只会修改第2行(索引1)的第3列(索引2)元素,其他行不受影响。
内容的提问来源于stack exchange,提问作者Ken
相关产品推荐
相关产品推荐

