何时使用dup,何时在Ruby中使用clone?

And*_*imm 13 ruby clone idiomatic dup

Ruby的dup和clone方法有什么区别?描述dup和的行为的差异clone.但是什么时候应该使用dup,何时应该使用clone

实际项目的例子讨论了为什么他们使用dup而不是克隆,反之亦然,这对于这个问题来说是理想的.

或者,解释为什么存在两种不同的方法会有所帮助.这可能是指从红宝石的创造者,或类似的方法检查报表dup,并clone在影响Ruby等语言.

Pat*_*ity 8

确实clone复制了frozen对象的状态,而dup不是:

o = Object.new
o.freeze

o.clone.frozen?
#=> true

o.dup.frozen?
#=> false
Run Code Online (Sandbox Code Playgroud)

clone还将复制对象的单例方法,而dup不是:

o = Object.new
def o.foo
  42
end

o.clone.respond_to?(:foo)
#=> true

o.dup.respond_to?(:foo)
#=> false
Run Code Online (Sandbox Code Playgroud)

这导致我clone有时被理解为提供比"更深"的副本的假设dup.以下是有关该主题的一些引用:

ActiveRecord::Base#initialize_dup来自Rails 3的评论:

Duped对象没有分配id并被视为新记录.请注意,这是一个"浅"副本,因为它只复制对象的属性,而不是它的关联."深层"副本的范围是特定于应用程序的,因此留给应用程序根据其需要实现.

关于Ruby中的深层副本的文章:

还有另一种方法值得一提,clone.该clone方法dup与一个重要的区别完全相同:预期对象将使用可以执行深层复制的方法覆盖此方法.

但是再一次,deep_dupRails 4中的theres:

如果对象是可复制的,则返回该对象的深层副本.如果它不可复制,则返回self.

并且还ActiveRecord::Core#dup#clone在轨道4,5:

clone - 与Ruby的克隆方法相同.这是一个"浅薄"副本.请注意,不会复制您的属性.[...]如果您需要属性哈希的副本,请使用该#dup方法.

这意味着在这里,该词dup用于再次引用深度克隆.据我所知,社区似乎没有达成共识,除非您需要使用,clone并且dup在您需要任何一方的特定副作用时.

最后,我dup在Ruby代码中看到的更多clone.我到目前为止从未使用过clone,直到明确需要,我才会这样做.


wal*_*.ar 5

DUP和CLONE都可用于创建对象的浅表副本.两者都复制了obj的实例变量.但我们需要选择使用它们.

这些之间几乎没有区别

1)CLONE复制对象的FROZEN和TAINTED状态,其中DUP仅复制对象的TAINTED状态.

2)使用CLONE,您可以复制对象的任何单例方法,但DUP不支持此方法.

CLONE用于复制对象,包括其内部状态,DUP通常使用后代对象的类来创建新实例.

我在使用DUP复制ActiveRecord行时遇到了一些痛苦的经历,最终失去原来的一个同样与CLONE一起正常工作.

当我把自己包裹在混乱之中时,我发现在开源文章中是明确的

  • Operator =不做浅拷贝,它只会复制对象参考!这句话完全是错的.另外:#dup和#clone之间的区别只是处理冻结状态.我认为为两者实现不同的复制算法是一个坏主意 - 无论是深度还是浅度.关于两者之间性能差异的数字在哪里?我会非常惊讶地看到显着的差异,因为两者基本相同.你能指出数字吗? (3认同)