clone
dup
生成某对象的拷贝并返回它.
clone生成的是完整的拷贝,它包括freeze、taint和特殊方法等信息; 而dup则只拷贝对象的内容.
请注意,clone 和 dup 生成的都是"浅层(shallow)"拷贝.它们只拷贝对象本身,而不会拷贝对象的所指(例如数组的元素等).
另外,如果对拷贝进行如下测试的话
obj.equal?(obj.clone)
通常都不成立.但是
obj == obj.clone
通常都会成立.
若想对true, false, nil, Symbol对象等进行拷贝时,会引发TypeError异常.
ruby 1.7 特性: 在1.7版本中,若想对Numeric对象等immutable(内容不可改变)的对象进行拷贝时,会引发TypeError.
于是求深层clone
Marshal.dump(obj[,port][,limit])
把obj递归地写入文件. 若对那些不能被写入文件的对象使用该函数时, 会引发TypeError异常. 下列对象就不能被写入文件.
无名的Class/Module对象. (此时,将引发ArgumentError异常. 请参考Module.new来了解无名类的情况.)
其状态受到系统保护的那些对象. 具体说来就是以下实例. 例如Dir, File::Stat, IO及其子类File, Socket等.
MatchData, Data, Method, UnboundMethod,Proc, Thread, ThreadGroup, Continuation的实例.
定义了特殊方法的对象
不是,只要去覆盖 Object 父类的 clone 方法,让浅层次克隆返回的对象的成员变量依次被克隆即可,而如果这个被克隆的成员内部还有成员,那么也应该再次被克隆(层层嵌套),这样就是深层次的克隆了,比如 Array 的深层次克隆:a = [[[1], 2], [3, 4]]复制代码
- class Array
- def clone
- obj = super
- for i in 0...obj.size
- begin
- obj[i] = self[i].clone
- rescue TypeError
- next
- end
- end
- return obj
- end
- end
b = a.clone
b[0][0][0] = 32767
p a[0][0][0] # <-- 1
让一个引用变量 obj 来保存最终克隆后的对象,先调用 super 获取 Object 类提供的浅层次克隆后的本对象(是一个数组),然后枚举它的每一个元素,克隆这个元素并保存到原地,如果这个元素是一个数组,那么调用这个元素的 clone 方法就会再次重复同样的步骤,否则的话则按照原来的方式去克隆其它类型的对象~
Array 等 Ruby 的底层类比较特殊,因为是 C 写的,所以无法去获取这个类中的成员变量,像 Array 就只能通过 [] 方法来克隆它的元素,所以需要单独去写它的深层 clone 方法
欢迎光临 Project1 (https://rpg.blue/) | Powered by Discuz! X3.1 |