zoukankan      html  css  js  c++  java
  • Ruby中如何复制对象 (deep clone)(转载)

    Ruby中如何复制对象 (deep clone)

    用Ruby复制一个对象(object)也许没有你想像的那么容易. 今天我google了半天, 做个总结吧.
    先从最简单的开始, b = a 是复制吗? 看代码说话:

    a= [0,[1,2]]
    b=a
    b[0]=88
    b[1][0]=99
    b 
    => [88, [99, 2]]
    a 
    => [88, [99, 2]]
    

    从上面代码发现, 一但修改b, 原来的a也同时被改变了. 甚至:

    b.equal?(a)
    => true
    

    原来b跟a根本就是同一个object, 只是马甲不一样罢了. 所以b = a不是复制.
    那 b = a.dup呢??

    还是看代码:

    a= [0,[1,2]]
    b=a.dup
    b[0]=88
    b[1][0]=99
    b
    => [88, [99, 2]]
    a
    => [0, [99, 2]]
    

    情况似乎有所好转, 在修改b后, a还是有一部分被修改了.(0没有变,但原来的1变成了99).
    所以dup有时候是复制(如在Array只有一级时), 但有时不是复制哦.

    再来一个, b = a.clone呢? 上代码:

    a= [0,[1,2]]
    b=a.clone
    b[0]=88
    b[1][0]=99
    b
    => [88, [99, 2]]
    a
    => [0, [99, 2]]
    

    情况几乎跟dup一模一样. 所以clone也不一定可以相信哦!
    原来ruby中的dup和clone都是shallow复制, 只针对object的第一级属性.
    汗, 难道在Ruby中没有办法复制对像吗? 也不完全是, 看这个:

    a= [0,[1,2]]
    b=Marshal.load(Marshal.dump(a))
    b[0]=88
    b[1][0]=99
    b
    => [88, [99, 2]]
    a= [0,[1,2]]
    => [0, [1, 2]]
    

    修改b后a没有被改变!!! 似乎终于成功找到复制的办法了!!!
    为什么要加"似乎"呢? 因为有些object是不能被Marshal.dump的.如:

    t=Object.new
    def t.test; puts ‘test’ end
    Marshal.dump(t)
    TypeError: singleton can’t be dumped
    from (irb):59:in `dump’
    from (irb):59
    

    更完善的复制方案可以考虑给ruby增加一个deep clone功能, 可以参考以下链接:
    http://d.hatena.ne.jp/pegacorn/20070417/1176817721
    http://www.artima.com/forums/flat.jsp?forum=123&thread=40913
    好了, 复制这个小问题, 没想到也能引出这么长的文章来, 没想到吧?

    忘记原文地址了,如有侵权,请告知!

  • 相关阅读:
    Thrust--self-defined(4)
    x86---32汇编(3)---内存寻址模式
    x86---32汇编(2)---局部变量
    x86---32汇编(1)---乘除法
    CUDA--Thrust(3)--List
    CUDA-Thrust(2)--野指针转换
    CUDA-Thrust(1)--函数初始化
    CUDA---Thrust(0)--初始化
    python(13)--Numpy的安装
    20200930 day24 刷题记录
  • 原文地址:https://www.cnblogs.com/jerrychen/p/4724977.html
Copyright © 2011-2022 走看看