Ruby 的 dup 和 clone 方法有什么区别?描述 和 的行为dup
差异clone
。但是我应该什么时候使用dup
,什么时候应该使用clone
呢?
来自实际项目的示例讨论了为什么他们使用 dup 而不是 clone,反之亦然,对于这个问题来说是理想的。
或者,解释为什么存在两种不同的方法会有所帮助。这可能是指来自 Ruby 的创建者的陈述,或者是对影响 Ruby 的语言dup
等方法的检查。clone
Ruby 的 dup 和 clone 方法有什么区别?描述 和 的行为dup
差异clone
。但是我应该什么时候使用dup
,什么时候应该使用clone
呢?
来自实际项目的示例讨论了为什么他们使用 dup 而不是 clone,反之亦然,对于这个问题来说是理想的。
或者,解释为什么存在两种不同的方法会有所帮助。这可能是指来自 Ruby 的创建者的陈述,或者是对影响 Ruby 的语言dup
等方法的检查。clone
确实会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 并被视为新记录。请注意,这是一个“浅”副本,因为它仅复制对象的属性,而不是其关联。“深”副本的范围是特定于应用程序的,因此留给应用程序根据其需要来实现。
还有一种方法值得一提,
clone
. 该clone
方法的作用dup
与一个重要区别相同:预计对象将使用可以进行深度复制的方法覆盖此方法。
如果它是可复制的,则返回对象的深层副本。如果它不可复制,则返回
self
.
以及在 Rails 4ActiveRecord::Core#dup
中#clone
:
clone
— 与 Ruby 的克隆方法相同。这是一个“浅”的副本。请注意,您的属性不会被复制。[...]如果您需要属性哈希的副本,请使用该#dup
方法。
这意味着在这里,该词dup
再次用于指代深层克隆。据我所知,社区似乎没有达成共识,除了你应该使用clone
和dup
在你需要任何一个特定副作用的情况下。
最后,我在 Ruby 代码中看到dup
的比clone
. clone
到目前为止我从未使用过,直到我明确需要时才会使用。
DUP 和 CLONE 都可用于创建对象的浅表副本。两者都复制了 obj 的实例变量。但是我们需要有选择性地使用它们。
这些之间几乎没有区别
1) CLONE 复制对象的 FROZEN 和 TAINTED 状态,而 DUP 仅复制对象的 TAINTED 状态。
2) 使用 CLONE,您可以复制对象的任何单例方法,但 DUP 不支持这一点。
CLONE 用于复制对象,包括其内部状态,DUP 通常使用后代对象的类来创建新实例。
我在使用 DUP 复制 ActiveRecord 行时遇到了一些痛苦的经历,这最终导致丢失了与 CLONE 相同的原始行。
当我把自己包裹起来时,我发现在一篇文章中很清楚 Open Source is Wide Open