【问题标题】:Is .dup really creating a shallow copy?.dup 真的创建了一个浅拷贝吗?
【发布时间】:2016-11-17 02:49:57
【问题描述】:

我在理解浅拷贝和#dup 方法的概念时遇到了一些麻烦

我有这个代码

class MyObject
end

myObject1 = MyObject.new
myObject2 = MyObject.new

我知道这会打印错误,因为我正在测试对象相等性,而不是值相等性

p myObject1 == myObject2

但是根据definition的浅拷贝

.dup 生成 obj 的浅拷贝——拷贝 obj 的实例变量,但不拷贝它们引用的对象。

我原以为这会打印出 true,但它也会打印出 false

p myObject1 == myObject1.dup

那不是定义错了吗? myObject1.dupinstance variable 不应该指向与 myObject1 相同的对象,除非它显然不是?

【问题讨论】:

    标签: ruby


    【解决方案1】:

    你忘了==实际上是来自BasicObject的方法:

    obj == other → true or false
    平等——在对象级别,== 仅当 obj 和其他对象是同一个对象时才返回 true。通常,此方法在后代类中被覆盖以提供特定于类的含义。

    因此,如果您没有提供自己的 == 实现(即 MyObject#== 方法),那么您的:

    p myObject1 == myObject1.dup
    

    和说的差不多:

    p myObject1.object_id == myObject1.dup.object_id
    

    由于myObject1.dupmyObject1 的浅拷贝(即它们是不同的对象),因此您会得到false

    当他们说:

    obj 的实例变量被复制

    他们指的是实例变量inside obj,而不是碰巧引用obj 的变量。您的myObject1 不是任何实例变量,它只是一个变量,实例变量以@ 开头,如@my_instance_variable

    如果您希望 == 以您期望的方式行事,那么您必须提供自己的 == 实现:

    class MyObject
      def ==(other)
        # Check that the contents of `self` and `other` are the same
        # and probably that `other.is_a?(MyObject)` first.
      end
    end
    

    【讨论】:

    • 不完全是我要问的。我的意思是,这个定义.dup produces a shallow copy of obj—the instance variables of obj are copied, but not the objects they reference. 不是暗示p myObject1 == myObject1.dup 应该打印正确吗?基本上,这种语言听起来像是.dup 复制了指针,但它们仍然指向同一个对象。明白我现在要问的了吗?
    • 但是myObject 只是一个变量(不是实例变量),文档说dup 复制了实例变量inside objmyObject1myObject1.dup 是完全不同的对象,您没有提供自己的 == 所以 myObject1 == myObject1.dupfalse。我还在回答中添加了一些说明,因此我将忽略那个白痴。
    • 非常感谢,我终于明白了。我基本上把instance variablepointer 混淆了
    猜你喜欢
    • 2015-09-08
    • 2018-10-07
    • 2011-10-13
    • 1970-01-01
    • 1970-01-01
    • 2012-04-12
    • 2013-04-06
    • 1970-01-01
    • 2011-06-03
    相关资源
    最近更新 更多