zoukankan      html  css  js  c++  java
  • Ruby中的深浅拷贝

      今天在写程序时,发现有两个测试单独运行通过,但一起运行时第二个测试老挂。不用说,产生了依赖了么,找了半天,找到这么两句。

    line_string = @@digital_lines[item][line_number]
    ...
    line_string.insert(1,"  ")
    

      在irb中测试了一下,原来line_string只是一个指针呀,直接就把原始数据给修改了,这不就是鼎鼎大名的深浅拷贝么,汗~~~

      没办法,在Google上面搜了一下,使用了Object中的dup方法,该方法类似于clone方法,返回一个相同值的全新对象,完成深拷贝,参考如下:

    ruby-1.8.7-p330 :010 > a = "123"
     => "123" 
    ruby-1.8.7-p330 :011 > b = a.dup
     => "123" 
    ruby-1.8.7-p330 :012 > a.object_id
     => 2149191580 
    ruby-1.8.7-p330 :013 > b.object_id
     => 2149174920 
    

      可以看出,a和b时两个不同的对象,当然也就不存在相互影响的情况了。

      大功告成了么?No, no, no. 好戏还没有结束,各位看官请往下看  

    ruby-1.8.7-p330 :062 > a = [["abc"]]
     => [["abc"]] 
    ruby-1.8.7-p330 :063 > b = a.dup
     => [["abc"]] 
    ruby-1.8.7-p330 :064 > a.object_id
     => 2149153820 
    ruby-1.8.7-p330 :065 > b.object_id
     => 2149144160 
    ruby-1.8.7-p330 :066 > a[0][0] = 1
     => 1 
    ruby-1.8.7-p330 :067 > a
     => [[1]] 
    ruby-1.8.7-p330 :068 > b
     => [[1]]
    

      虽然调用了dup方法产生了不同的对象,但还是出现了浅拷贝的情况(当a[0][0]=1时,b的值也变了)。同样的情况还出现在Hash和我们自定义的类中。

      想一想我们在C++和Java中时如何解决这个问题的?聪明的你一定想到了吧,既然系统自带的不给力,咱就自己写一个吧。实际上,已经有牛人写好了,我们直接用就行了,嘿嘿~~

      参考如下:http://www.artima.com/forums/flat.jsp?forum=123&thread=40913

      

    class Object
          def dclone
            case self
              when Fixnum,Bignum,Float,NilClass,FalseClass,
                   TrueClass,Continuation
                klone = self
              when Hash
                klone = self.clone
                self.each{|k,v| klone[k] = v.dclone}
              when Array
                klone = self.clone
                klone.clear
                self.each{|v| klone << v.dclone}
              else
                klone = self.clone
            end
            klone.instance_variables.each {|v|
              klone.instance_variable_set(v,
                klone.instance_variable_get(v).dclone)
            }
            klone
          end
        end
    

      还等什么,赶紧Command+C走吧~~~

    PS:前文提到了dup和clone差不多,那Object中的dup和clone的区别是什么呢?

    答案在这里,需要饭强哦(fan qiang是敏感词。。。)。

      

  • 相关阅读:
    Django错误笔记1
    Django学习笔记1 启动及配置一个Django项目
    ubuntu 安装mysqldb
    二叉树 总结
    序列二叉树和反序列 (不是自己做的)
    二叉树的路径
    二叉搜索树的后续遍历
    二叉树层序遍历
    栈的压入 弹出序列
    包含 min的栈
  • 原文地址:https://www.cnblogs.com/iammatthew/p/2199680.html
Copyright © 2011-2022 走看看