ruby - 如何理解#dup 和#clone 对引用其他对象的对象进行操作?

标签 ruby object clone dup

我不确定 “...但不是它们引用的对象”rubyrubinus 文档中的含义>.

ruby-doc ,有 #clone#dup 行为的解释:

Produces a shallow copy of obj—the instance variables of obj are copied, but not the objects they reference. Copies the frozen and tainted state of obj. See also the discussion under Object#dup.

Rubinius 的实现中重复相同的操作:

Copies instance variables, but does not recursively copy the objects they reference. Copies taintedness.

我尝试了以下代码,但行为超出了我的预期。

class Klass
   attr_accessor :array
end

s1 = Klass.new
ar = [1, 2, 3]
s1.array = [ar]

s2 = s1.clone
# according to the doc,
# s2.array should be initialized with empty Array
# however the array is recursivley copied too

s2.array.equal? s1.array # true

最佳答案

在 Ruby 中,所有对象都是引用。看看下面的例子:

class Klass
  attr_accessor :a
end

s1 = Klass.new
a = [1,2,3]
s1.a = a
s2 = s1.clone
s1.a.object_id  #=> 7344240 
s2.a.object_id  #=> 7344240 

您可以看到这两个数组是同一个对象,并且都是对堆中某处数组的引用。在深层复制中,数组本身将被复制,新的 s2 将拥有自己的不同数组。数组没有被复制,只是被引用。

注意: 如果你做一个深拷贝,它看起来像这样:

s3 = Marshal.load(Marshal.dump(s1)) #=> #<Klass:0x00000000bf1350 @a=[1, 2, 3, 4], @bork=4> 
s3.a << 5 #=> [1, 2, 3, 4, 5] 
s1 #=> #<Klass:0x00000000e21418 @a=[1, 2, 3, 4], @bork=4> 

关于ruby - 如何理解#dup 和#clone 对引用其他对象的对象进行操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16192912/

相关文章:

mysql - 计算 Rails 中的日期列

ruby - <top (required)> 中的 block (3 级)

javascript - 带或不带引号的 JS 对象键?

Java:如何将克隆对象转换为其原始子类?

mercurial - 什么是Mercurial hg克隆语法将存储库克隆到本地文件系统上的文件夹

ruby - Ruby 哈希是否有类似 `reject!` 的方法返回匹配项?

ruby Restclient超时无法正常工作,它在定义的超时加倍后抛出异常

json - 如何访问 Dart 中对象列表中的对象列表

javascript - 如果属性存在,是否有一个函数仅在目标上分配属性?

ruby - 在 Ruby 中对克隆的散列使用 gsub 会修改原始散列