我正在尝试深度复制一个包含3D数组的对象。但它没有按预期工作。
class A
def initialize
@a = [[[1]], [[2]]]
end
def modify3D
@a[0][0] = @a[1][0]
end
def modify2D
@a[0] = @a[1]
end
def dup
copy = super
copy.make_independent!
copy
end
def make_independent!
@a = @a.dup
end
def show
print "\n#{@a}"
end
end
a = A.new
b = a.dup
#a.modify2D
b.show
a.modify3D
b.show
在这种情况下,b由a上的modify3D调用更改。
[[[1]], [[2]]]
[[[2]], [[2]]]
如果我取消注释modify2D行,一切正常。
[[[1]], [[2]]]
[[[1]], [[2]]]
有人可以解释一下这里发生了什么吗?
答案 0 :(得分:2)
您的副本不够深入。 Array#dup只复制数组本身,而不是数组元素。您最终会得到两个仍然共享相同元素的不同数组。
在this answer中,我展示了如何使用marshaling进行深层复制。这种方法可以完成所有工作:
def deep_copy(o)
Marshal.load(Marshal.dump(o))
end
deep_copy适用于任何可以封送的对象。大多数内置数据类型(Array,Hash,String和& c。)都可以编组。实例变量可以封送的任何对象本身都可以被封送。
定义了deep_copy,然后替换这一行:
b = a.dup
用这个:
b = deep_copy(a)
它应该像你期望的那样工作。