Ruby中函数操作传入数组参数意外修改全局数组的问题
问题复现
我有一个嵌套了8个子数组的数组,还有一个将所有内容拼接后返回的函数,但不知为何该函数会修改全局数组,即便我没有主动做相关操作。我希望可以在函数中使用map,但如果我没有在函数中显式使用map的话,不希望出现全局数组被修改的情况。
对应代码如下:
def joinArray(array) for i in 0..(array.length() - 1) do array[i] = array[i].join() end return array end $map = Array.new(8){Array.new(8)} for i in 0..7 do for x in 0..7 do $map[i][x] = $square end end # 调用函数前,$map的结构是 [["0", "0", "0", ...], ["0", "0", ...], ...] puts (joinArray($map)).join("\n") # 调用函数后,$map变成了 ["00000000","00000000", ...]
原因说明
Ruby的参数传递是引用传递,不会自动为传入的参数创建独立副本。你在joinArray函数中执行array[i] = array[i].join()操作时,array就是全局变量$map的引用,直接修改array的元素等价于直接修改原全局数组,自然会产生修改原变量的副作用。
你提到的传入$map.dup的方案是可行的,dup方法会创建原数组的浅拷贝,函数内修改的是拷贝后的数组,不会影响原全局数组。
无副作用优化方案
如果不想修改原数组,更推荐直接用map生成新数组返回,完全不需要修改传入的参数,函数本身不会产生任何副作用:
def joinArray(array) # map会遍历原数组生成新数组,不会修改原数组内容 array.map { |sub_array| sub_array.join } end
调用时直接传原$map即可,调用后原数组依然会保留原来的二维结构:
puts joinArray($map).join("\n")
内容的提问来源于stack exchange,提问作者user16610513
相关产品推荐
相关产品推荐

