`Marshal.load Marshal.dump array`和`array.map(&:dup)`之间的区别

时间:2017-01-20 23:03:14

标签: arrays ruby

我在another answer中读到了首选使用array.map(&:dup)

  

除非你真的想深度复制整个对象图,否则不要使用编组技巧。通常,您只想复制数组,而不是复制包含的元素。

很想看到一个例子来说明这两种方法之间的区别。

除了语法之外,它看起来像是在做同样的事情。

很想了解Marshal#dup之间差异的更多信息。

    arr = [ [['foo']], ['bar']]
    foo = arr.clone
    p arr #=> [[["foo"]], ["bar"]]
    p foo #=> [[["foo"]], ["bar"]]
    foo[0][0] = 42
    p arr #=> [[42], ["bar"]]
    p foo #=> [[42], ["bar"]]

    arr = [ [['foo']], ['bar']]
    foo = Marshal.load Marshal.dump arr
    p arr #=> [[["foo"]], ["bar"]]
    p foo #=> [[["foo"]], ["bar"]]
    foo[0][0] = 42
    p arr #=> [[["foo"]], ["bar"]]
    p foo #=> [[42], ["bar"]]

    arr = [ [['foo']], ['bar']]
    foo = arr.map(&:dup)
    p arr #=> [[["foo"]], ["bar"]]
    p foo #=> [[["foo"]], ["bar"]]
    foo[0][0] = 42
    p arr #=> [[["foo"]], ["bar"]]
    p foo #=> [[42], ["bar"]]

1 个答案:

答案 0 :(得分:0)

元帅技巧还克隆了数组的元素

array = [[Object.new]]

在复制之前和之后检查元素的object_id

array.first.first.object_id
# => 70251489489120

array.map(&:dup).first.first.object_id
# => 70251489489120 -- the same

(Marshal.load Marshal.dump array).first.first.object_id
# => 70251472965580 -- different object!

除非你真的想深度复制整个对象图,否则不要使用编组技巧。通常,您只想复制数组,而不是复制包含的元素。