Ruby clone? dup? =?

calebx · 2012年03月22日 · 最后由 skandhas 回复于 2012年03月22日 · 6548 次阅读

clone dup 和= 到底是啥区别?

a = {:x=>'xxx', :y=>'yyy', :z=>{:zz=>"zzz"}}
b = a
c = a.clone
d = a.dup

b[:x] = 'bbb'
c[:y] = 'ccc'
d[:z][:zz] = 'ddd'

p a
p b
p c
p d

{:x=>"bbb", :y=>"yyy", :z=>{:zz=>"ddd"}} {:x=>"bbb", :y=>"yyy", :z=>{:zz=>"ddd"}} {:x=>"xxx", :y=>"ccc", :z=>{:zz=>"ddd"}} {:x=>"xxx", :y=>"yyy", :z=>{:zz=>"ddd"}}

肿么解释?

b.object_id == a.object_id c.object_id != a.object_id d.object_id != a.object_id

b 相当于 a 的别名,c、d 是新的实例。 c、d 复制了 a 的数据,但不复制引用的内容。 clone 出来的实例保留 frozen 状态,dup 出来的不保留。

=可以理解为指针,或引用 clone 和 dup 都是浅拷,你的这个例子里写 clone 和 dup 都一样。因为浅拷,所以这个:z 只拷指针,不拷内容,一改变全变。

我看了一下源码,clone 和 dup 主要不同是,clone 可以拷到 engienclass,而 dup 不行。如:

s = "123456"
def s.fun;p 'haha';end
s.clone.fun #=>成功
s.dup.fun #=>undefined method `fun'



还有就是楼上的 FREEZE 状态。

这个帖子也进行了讨论: http://ruby-china.org/topics/1712

需要 登录 后方可回复, 如果你还没有账号请 注册新账号