13

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

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

或者,解释为什么存在两种不同的方法会有所帮助。这可能是指来自 Ruby 的创建者的陈述,或者是对影响 Ruby 的语言dup等方法的检查。clone

4

2 回答 2

8

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

o = Object.new
o.freeze

o.clone.frozen?
#=> true

o.dup.frozen?
#=> false

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

o = Object.new
def o.foo
  42
end

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

o.dup.respond_to?(:foo)
#=> false

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

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

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

一篇关于 Ruby 中的深拷贝的文章

还有一种方法值得一提,clone. 该clone方法的作用dup与一个重要区别相同:预计对象将使用可以进行深度复制的方法覆盖此方法。

但话又说回来,deep_dup在 Rails 4 中有

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

以及在 Rails 4ActiveRecord::Core#dup#clone

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

这意味着在这里,该词dup再次用于指代深层克隆。据我所知,社区似乎没有达成共识,除了你应该使用clonedup在你需要任何一个特定副作用的情况下。

最后,我在 Ruby 代码中看到dup的比clone. clone到目前为止我从未使用过,直到我明确需要时才会使用。

于 2014-05-28T20:11:22.083 回答
5

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

这些之间几乎没有区别

1) CLONE 复制对象的 FROZEN 和 TAINTED 状态,而 DUP 仅复制对象的 TAINTED 状态。

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

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

我在使用 DUP 复制 ActiveRecord 行时遇到了一些痛苦的经历,这最终导致丢失了与 CLONE 相同的原始行。

当我把自己包裹起来时,我发现在一篇文章中很清楚 Open Source is Wide Open

于 2012-08-01T04:17:46.967 回答