Ruby复制对象
Ruby对象复制
对象复制:dup()、clone()
Ruby中可以使用Object#dup()
或Object#clone()
来浅拷贝对象,它们基本等价,区别稍后再谈。下面是使用dup()复制一个对象的示例:
1 | class C |
上面使用dup()复制对象c得到对象c1,c和c1两个对象除了少数几个属性,其它状态和属性是一样的,比如实例变量的值相同,具有的实例方法相同,方法的可见性规则相同(即public/private/protected),等等。
dup()和clone()有几点不同:
initialize_dup、initialize_clone和initialize_copy的区别
无论是dup()还是clone(),它们在处理了一些逻辑后,会分别调用initialize_dup()
和initialize_clone()
。
dup()和clone()的伪代码大概是这样的:
1 | # 伪代码:在Object中如下定义dup和clone方法 |
initialize_dup()
和initialize_clone()
在内部又会继续调用initialize_copy()
,在Rubinus的core/kernel.rb中有如下代码,可知它们的关系:
1 | # 在core/kernel.rb中: |
所以,如果自己手动重写initialize_dup
和initialize_clone
时,建议也调用一下initialize_copy
,或者直接super一下(其实就是在调用initialize_copy)。
那么重写这三个方法有什么用呢?如果在复制对象的时候,有些属性不想复制,比如随机数、时间点、ID等各对象独立的属性,那么可以重写这些方法。
要注意:
- 在重写这些方法的时候,这些方法是在复制并填充完对象属性后再调用的,所以在这些方法中只需要修改那些需要修改的属性即可
- 这三个方法内的self指向的是拷贝出的对象,它们还接受一个参数other,other是被复制的源参照对象,例如
c1 = c.dup
,那么other是源对象c,这三个方法内的self是新对象c1
例如,不想在复制对象的时候连对象的@create_time
时间点也复制,而是定义为复制时的时间点。直接重写initialize_copy
即可。
1 | class C |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 骏马金龙!
评论