摘要:對于而言,情況可能會有點小復雜,因為一切皆為對象,所以的普通賦值深拷貝和淺拷貝之間都是有細微區別的。二下的他們在中,對象的賦值和傳遞都是引用。
一、深拷貝與淺拷貝
??深拷貝:賦值時值完全復制,完全的copy,對其中一個作出改變,不會影響另一個
??淺拷貝:賦值時,引用賦值,相當于取了一個別名。對其中一個修改,會影響另一個
??對于PHP而言,= 賦值時,普通對象是深拷貝,但對對象來說,是淺拷貝,即引用賦值。當對象作為參數傳遞時,無論參數前是否有&引用符號,都將被看做是賦值引用。
??對于python而言,情況可能會有點小復雜,因為python一切皆為對象,所以python的普通賦值、深拷貝和淺拷貝之間都是有細微區別的。
二、php下的他們??在php5中,對象的 = 賦值和傳遞都是引用。要想實現拷貝副本,php提供了clone函數實現。clone完全copy了一份副本。但是clone時,我們可能不希望copy源對象的所有內容,那我們可以利用__clone來操作。
請看如下代碼段:
a = 2;//修改m,n也隨之改變 echo $n->a;//輸出2,淺拷貝 echo PHP_EOL; ?>
??由于對象的賦值時引用,要想實現值復制,php提供了clone函數來實現復制對象。但是clone函數存在這么一個問題,克隆對象時,原對象的普通屬性能值復制,但是源對象的對象屬性賦值時還是引用賦值,淺拷貝。
obj = new Test(); } } $m = new TestOne(); $n = $m;//這是完全的淺拷貝,無論普通屬性還是對象屬性 $p = clone $m; //普通屬性實現了深拷貝,改變普通屬性b,不會對源對象有影響 $p->b = 2; echo $m->b;//輸出原來的1 echo PHP_EOL; //對象屬性是淺拷貝,改變對象屬性中的a,源對象m中的對象屬性中a也改變 $p->obj->a = 3; echo $m->obj->a;//輸出3,隨新對象改變 ?>
??要想實現對象真正的深拷貝,有以下兩種方法:
1、利用序列化反序列化實現
obj = new Test(); } } $m = new TestOne(); //方法二,序列化反序列化實現對象深拷貝 $n = serialize($m); $n = unserialize($n); $n->b = 2; echo $m->b;//輸出原來的1 echo PHP_EOL; //可以看到,普通屬性實現了深拷貝,改變普通屬性b,不會對源對象有影響 $n->obj->a = 3; echo $m->obj->a;//輸出1,不隨新對象改變,還是保持了原來的屬性,可以看到,序列化和反序列化可以實現對象的深拷貝 ?>
2、寫clone函數
obj = new Test(); } //方法一:重寫clone函數 public function __clone(){ $this->obj = clone $this->obj; } } $m = new TestOne(); $n = clone $m; $n->b = 2; echo $m->b;//輸出原來的1 echo PHP_EOL; //可以看到,普通屬性實現了深拷貝,改變普通屬性b,不會對源對象有影響 //由于改寫了clone函數,現在對象屬性也實現了真正的深拷貝,對新對象的改變,不會影響源對象 $n->obj->a = 3; echo $m->obj->a;//輸出1,不隨新對象改變,還是保持了原來的屬性 ?>三、python下的他們
??“對一個對象進行淺拷貝其實是新創建了一個類型和原來對象一樣,但是內容是原來對象元素的引用。換句話說,這個拷貝的對象本身是新的,但是它的內容不是”,摘自《Python核心編程》。
??這是我個人對python下淺拷貝和深拷貝的理解:
賦值:簡單地拷貝對象的引用,兩個對象的id相同。
淺拷貝:創建一個新的組合對象,這個新對象與原對象共享內存中的子對象。
深拷貝:創建一個新的組合對象,同時遞歸地拷貝所有子對象,新的組合對象與原對象沒有任何關聯。雖然實際上會共享不可變的子對象,但不影響它們的相互獨立性。
??淺拷貝和深拷貝的不同僅僅是對組合對象來說,所謂的組合對象就是包含了其它對象的可變對象,如列表,類實例。而對于數字、字符串以及其它“原子”類型,沒有拷貝一說,產生的都是原對象的引用。
下面的代碼希望能對你有進一步的幫助;
#! /usr/bin/python # -*- coding:UTF-8 -*- import copy # 淺拷貝 a = [1, "a", 3, [4, 5, 6], [[7, 8, 9]]] b = a c = list(a) d = copy.deepcopy(a) print "原地址&&&" print id(a) print "賦值地址&&&" print id(b) print "淺拷貝地址&&&" print id(c) print "深拷貝地址&&&" print id(d) print "賦值地址###" for i, j in zip(a, b): print id(i), id(j) print "淺拷貝地址###" for i, j in zip(a, c): print id(i), id(j) print "深拷貝地址###" for i, j in zip(a, d): print id(i), id(j) print "######" a[0] = 2 a[3][0] = 14 print "原值變化為 %d, %d" % (a[0], a[3][0]) print "*******" print "賦值變化" print b[0], b[3][0] print "淺拷貝變化" print c[0], c[3][0] print "深拷貝變化" print d[0], d[3][0] print "**##$$" print a
輸出如下:
參考博文http://www.cnblogs.com/taijun...
http://blog.csdn.net/u0115085...
http://www.cnblogs.com/zxlove...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/30688.html
摘要:對于而言,情況可能會有點小復雜,因為一切皆為對象,所以的普通賦值深拷貝和淺拷貝之間都是有細微區別的。二下的他們在中,對象的賦值和傳遞都是引用。 一、深拷貝與淺拷貝 ??深拷貝:賦值時值完全復制,完全的copy,對其中一個作出改變,不會影響另一個 ??淺拷貝:賦值時,引用賦值,相當于取了一個別名。對其中一個修改,會影響另一個 ??對于PHP而言,= 賦值時,普通對象是深拷貝,但對對象來說...
摘要:參考鏈接淺拷貝最簡單的淺拷貝就賦值。所謂的淺拷貝就是,后面的對象和前面的對象在第一層數據結構中指向同一個堆地址。但是如果前面的數據不止有一層,如此時,使用和方式實現的都是淺拷貝。深拷貝管你怎么變,互不影響。 參考鏈接:http://www.cnblogs.com/st-les...https://blog.csdn.net/hj7jay/... 淺拷貝: 1.最簡單的淺拷貝就賦值。由于...
摘要:一篇文章徹底說清的深拷貝淺拷貝這篇文章的受眾第一類業務需要急需知道如何深拷貝對象的開發者。這篇文章分享的目的更多還是希望用一篇文章整理清楚深淺拷貝的含義遞歸實現思路以及小伙伴們如果使用了這種黑科技一定要清楚這樣寫的優缺點。 一篇文章徹底說清JS的深拷貝and淺拷貝 這篇文章的受眾 第一類,業務需要,急需知道如何深拷貝JS對象的開發者。 第二類,希望扎實JS基礎,將來好去面試官前秀操作...
摘要:一篇文章徹底說清的深拷貝淺拷貝這篇文章的受眾第一類業務需要急需知道如何深拷貝對象的開發者。這篇文章分享的目的更多還是希望用一篇文章整理清楚深淺拷貝的含義遞歸實現思路以及小伙伴們如果使用了這種黑科技一定要清楚這樣寫的優缺點。 一篇文章徹底說清JS的深拷貝and淺拷貝 這篇文章的受眾 第一類,業務需要,急需知道如何深拷貝JS對象的開發者。 第二類,希望扎實JS基礎,將來好去面試官前秀操作...
摘要:一篇文章徹底說清的深拷貝淺拷貝這篇文章的受眾第一類業務需要急需知道如何深拷貝對象的開發者。這篇文章分享的目的更多還是希望用一篇文章整理清楚深淺拷貝的含義遞歸實現思路以及小伙伴們如果使用了這種黑科技一定要清楚這樣寫的優缺點。 一篇文章徹底說清JS的深拷貝and淺拷貝 這篇文章的受眾 第一類,業務需要,急需知道如何深拷貝JS對象的開發者。 第二類,希望扎實JS基礎,將來好去面試官前秀操作...
閱讀 964·2021-11-24 10:42
閱讀 3475·2021-11-19 11:34
閱讀 2605·2021-09-29 09:35
閱讀 2525·2021-09-09 09:33
閱讀 641·2021-07-26 23:38
閱讀 2515·2019-08-30 10:48
閱讀 1385·2019-08-28 18:07
閱讀 422·2019-08-26 13:44