【问题标题】:Difference between `Marshal.load Marshal.dump array` and `array.map(&:dup)``Marshal.load Marshal.dump array` 和 `array.map(&:dup)` 之间的区别
【发布时间】:2017-01-20 23:03:14
【问题描述】:

我在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"]]

【问题讨论】:

  • array.map(&:dup) 已经足够好了,因为 map 无论如何都会创建一个副本,额外的 dup 是我其他答案中的错字

标签: arrays ruby


【解决方案1】:

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

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!

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

【讨论】:

    猜你喜欢
    • 2018-08-30
    • 2012-05-21
    • 2019-01-28
    • 2016-05-12
    • 2012-12-23
    • 2021-06-10
    • 2016-05-03
    • 1970-01-01
    相关资源
    最近更新 更多