Ruby中修改dup数组为何同步改变nums?迭代赋值疑问解析
测试代码
max = 99 nums = max.to_s.split('') (0..nums.length - 1).each do |i| dup = nums p 'dup', dup p 'nums', nums dup[i] = '6' end p 'result', nums
执行输出
"dup" ["9", "9"] "nums" ["9", "9"] "dup" ["6", "9"] "nums" ["6", "9"] "result" ["6", "6"]
疑问
- 为何修改dup数组的元素值时,原nums数组的元素值也会同步改变?
- 第一次迭代中
dup = nums似乎有效,而第二次迭代时dup = nums却未将dup重置为nums的初始状态,这是为什么?
解答
核心本质:Ruby数组是引用类型,赋值操作不复制对象
这两个问题根源完全一致:在Ruby里,数组属于引用类型——变量nums存储的不是数组本身,而是指向内存中数组对象的"地址引用"。当你写dup = nums时,并没有创建新数组,只是让dup这个变量也指向了nums所指向的同一个数组对象。
问题1解答
修改dup[i] = '6'时,你操作的是dup指向的那个数组对象——而这个对象和nums指向的是同一个内存地址的数组。不管用哪个变量去修改数组元素,本质都是在改动同一个数组对象,所以nums的元素必然同步变化。
问题2解答
第一次迭代时,nums指向的是初始的["9", "9"],所以dup = nums让dup也指向这个初始数组。但第一次迭代最后执行dup[0] = '6'时,直接修改了nums指向的数组对象内容——此时nums仍然指向原来的内存地址,但数组里的元素已经变成了["6", "9"]。
第二次迭代执行dup = nums时,nums当前指向的就是已经被修改过的数组,所以dup自然也指向这个改动后的数组,根本不存在"重置回初始状态"的可能——因为初始数组的内容已经被改动,nums本身的引用没变化,但它指向的对象内容变了。
正确的数组复制方式
如果想让dup成为独立于nums的新数组,修改它不影响原数组,需要用Ruby提供的数组复制方法(比如dup或clone):
max = 99 nums = max.to_s.split('') (0..nums.length - 1).each do |i| dup = nums.dup # 用dup方法创建数组的独立副本 p 'dup', dup p 'nums', nums dup[i] = '6' end p 'result', nums
执行这段代码会看到,每次dup都是nums的独立副本,修改dup不会改变nums,最终nums仍保持初始的["9", "9"]。
内容的提问来源于stack exchange,提问作者Praveen Raj005
相关产品推荐
相关产品推荐

