Ruby多维数组两种初始化方式操作结果差异咨询
Ruby多维数组初始化的行为差异解析
两种写法的本质区别
写法1:
arr = Array.new(3, Array.new(3, "x"))
这里Array.new的第二个参数是预先创建好的同一个数组对象。初始化时,Ruby会把这个对象的引用重复3次放进外层数组,也就是说arr[0]、arr[1]、arr[2]指向内存中同一个子数组。当执行arr[0][0] = "y"时,本质是修改这个共享子数组的元素,自然所有外层数组的子数组对应位置都会同步变化。写法2:
arr = Array.new(3) { Array.new(3) { "x" } }
这种写法用块作为参数,Array.new会为外层数组的每个元素执行一次块内代码,每次执行都会创建一个全新的子数组对象。因此arr[0]、arr[1]、arr[2]是三个完全独立的数组,修改其中一个的元素不会影响另外两个。
验证对象引用的差异
可以通过object_id方法直观看到区别:
- 写法1执行后,
arr[0].object_id == arr[1].object_id返回true,证明三个子数组是同一个对象; - 写法2执行后,
arr[0].object_id != arr[1].object_id返回true,证明三个子数组是独立对象。
补充说明
这种设计是Ruby的预期行为:
- 如果传入的是不可变对象(比如整数、符号),两种写法效果类似,因为不可变对象无法修改内部状态,只能替换引用;
- 但如果传入的是可变对象(比如数组、哈希),必须用块的方式才能创建独立的子对象,避免共享引用带来的意外修改。
内容的提问来源于stack exchange,提问作者Amriteya
相关产品推荐
相关产品推荐

