日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ruby中的复制 dup clone

發布時間:2024/4/15 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ruby中的复制 dup clone 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.


Ruby內置的方法Object#clone和Object#dup可以用來copy一個對象,兩者區別是dup只復制對象的內容,而clone還復制與對象相關聯的內容,如singleton method
[ruby] view plaincopyprint?
s = "cat"
def s.upcase
"CaT"
end
s_dup = s.dup
s_clone = s.clone
s_dup.upcase #=> "CAT" (singleton method not copied)
s_clone.upcase #=> "CaT" (uses singleton method)

dup和clone都是淺復制Shallow Copy,也就是只能復制接受方的內容,而如果接受方包含到其他對象的引用,那么就只是會復制這些引用了。
[ruby] view plaincopyprint?
arr1 = [ 1, "flipper", 3 ]
arr2 = arr1.dup
arr2[2] = 99
arr2[1][2] = 'a'
arr1 #=> [1, "flapper", 3]
arr2 #=> [1, "flapper", 99]
可以看到arr1中有一個到String對象的引用,從而arr2也復制了這個引用,當arr2中修改這個引用時,arr1中的也會發生變化。
如果要進行深復制Deep Copy,可以聰明的采用Marshal模塊
[ruby] view plaincopyprint?
arr1 = [ 1, "flipper", 3 ]
arr2 = Marshal.load(Marshal.dump(arr1))
arr2[2] = 99
arr2[1][2] = 'a'
arr1 #=> [1, "flipper", 3]
arr2 #=> [1, "flapper", 99]
現在就會發現arr2中對String對象的修改不會導致arr1的變化了,因為深了。。。不過Marshal模塊并不能把所有的對象都序列化
在class中還有一個與對象復制相關的特殊方法initialize_copy,這個方法會在信息復制完成后執行,看下面這個示例
[ruby] view plaincopyprint?
class Document
attr_accessor :title, :text
attr_reader :timestamp

def initialize(title, text)
@title, @text = title, text
@timestamp = Time.now
end
end

doc1 = Document.new("Random Stuff", "Haha")
sleep 10
doc2 = doc1.clone

doc1.timestamp == doc2.timestamp #=> true
也就是兩個對象是完全一樣的,構造函數initialize被跳過了,所以兩個對象的時間戮timestamp是相同的。如果要采用執行復制操作時的時間,我們可以通過給Document類添加initialize_copy方法來實現。initialize_copy讓程序員能完全控制對象復制的狀態
[ruby] view plaincopyprint?
class Document #Reopen the class
def initialize_copy(other)
@timestamp = Time.now
end
end

doc3 = Document.new("More Stuff", "Haha")
sleep 10
doc4 = doc1.clone

doc3.timestamp == doc4.timestamp #=> false
再次感慨Ruby的魅力。。。
PS:以上內容主要來自The Ruby Way

用Ruby復制一個對象(object)也許沒有你想像的那么容易. 今天我google了半天, 做個總結吧.
先從最簡單的開始, b = a 是復制嗎? 看代碼說話:
>> a= [0,[1,2]]
>> b=a
>> b[0]=88
>> b[1][0]=99
>> b
=> [88, [99, 2]]
>> a
=> [88, [99, 2]]
從上面代碼發現, 一但修改b, 原來的a也同時被改變了. 甚至:

>> b.equal?(a)
=> true
原來b跟a根本就是同一個object, 只是馬甲不一樣罷了. 所以b = a不是復制.
那 b = a.dup呢?? 還是看代碼:
>> a= [0,[1,2]]
>> b=a.dup
>> b[0]=88
>> b[1][0]=99
>> b
=> [88, [99, 2]]
>> a
=> [0, [99, 2]]
情況似乎有所好轉, 在修改b后, a還是有一部分被修改了.(0沒有變,但原來的1變成了99).
所以dup有時候是復制(如在Array只有一級時), 但有時不是復制哦.
再來一個, b = a.clone呢? 上代碼:
>> a= [0,[1,2]]
>> b=a.clone
>> b[0]=88
>> b[1][0]=99
>> b
=> [88, [99, 2]]
>> a
=> [0, [99, 2]]
情況幾乎跟dup一模一樣. 所以clone也不一定可以相信哦!
原來ruby中的dup和clone都是shallow復制, 只針對object的第一級屬性.
汗, 難道在Ruby中沒有辦法復制對像嗎? 也不完全是, 看這個:
>> a= [0,[1,2]]
>> b=Marshal.load(Marshal.dump(a))
>> b[0]=88
>> b[1][0]=99
>> b
=> [88, [99, 2]]
>> a= [0,[1,2]]
=> [0, [1, 2]]
修改b后a沒有被改變!!! 似乎終于成功找到復制的辦法了!!!
為什么要加"似乎"呢? 因為有些object是不能被Marshal.dump的.如:
>> t=Object.new
>> def t.test; puts ‘test’ end
>> Marshal.dump(t)
TypeError: singleton can’t be dumped
from (irb):59:in `dump’
from (irb):59
更完善的復制方案可以考慮給ruby增加一個deep clone功能, 可以參考以下鏈接:
http://d.hatena.ne.jp/pegacorn/20070417/1176817721

轉載于:https://www.cnblogs.com/qinyan20/p/9674004.html

總結

以上是生活随笔為你收集整理的ruby中的复制 dup clone的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。