Ruby对象ID,dup和可变性

时间:2014-09-10 23:30:57

标签: ruby clone dup

我在Ruby中遇到了以下问题

a = [1, 2, 3]
b = a
b.delete_at(1)
b => [1,3]
a => [1,3]
b.object_id => 70178446287080
a.object_id => 70178446287080

所以我对此有所了解。 a包含对object_id的数组的引用。

b也有对该SAME位置的引用,b指向a,引用其object_id。基本上他们指的是同一件事。因此,如果我为b变异,a也会发生变异。

这种行为属于哪种类别?是否有任何我能记住的读数/一般实践,所以我将来不会有任何错误?我知道a.dup会在其他位置提供新对象,因此a.dup == b将为true。也适用于a.dup.object_id == b.object_id

此外,dupclone在这种情况下基本上是一样的,无论是浅层还是深层?

1 个答案:

答案 0 :(得分:0)

#dup#clone都会创建对象的浅表副本。但是,#clone执行#dup没有做到的两件事:

  • 复制复制对象的单例类
  • 维护复制对象的冻结状态

单身人士的例子:

<强> #dup:

a = Object.new

def a.foo do
  :foo 
end

p a.foo
# => :foo

b = a.dup
p b.foo
# => undefined method `foo' for #<Object:0x007f8bc395ff00> (NoMethodError)

<强> #clone:

a = Object.new

def a.foo do
  :foo 
end

p a.foo
# => :foo

b = a.clone
p b.foo
# => :foo

冻结状态的示例:

a = Object.new

a.freeze
p a.frozen?
# => true

b = a.dup
p b.frozen?
# => false

c = a.clone
p c.frozen?
# => true

由于额外的步骤,#clone#dup慢一点(但可能不会使你的应用太慢!)。