值類型和引用類型

  • [值類型和引用類型]
    • [什么是值類型(value type)和引用類型(reference type)]
    • [兩者有什么不同]
    • [請在保證安全的情況下修改變量值]
    • [如何選擇]
    • [c++類型行為的不一致性]
    • [ 參考文章]

變量類型可以幫助開發(fā)者理清程序的數(shù)據(jù)流酣胀,以寫出更健壯的代碼城丧。本文通過對swift語言中的兩種變量類型的介紹垒在,來說明哪些情況下適合使用value/reference type拯杠。閱讀本文不需要對swift有深入了解碎捺,當然熟悉swift編程對理解本文會有幫助萝招。

什么是值類型(value type)和引用類型(reference type)

在swift中袜腥,一個類型要么是value type茬贵, 要么是reference type郊霎。value type指每一個變量在內存中都有單獨的一份數(shù)據(jù)拷貝沼头。reference type指數(shù)據(jù)在內存中只有一份拷貝,多個變量共享它的值书劝。和c++中類型的使用方式不同进倍,swift中類型的屬性(value/reference)是由類型本身決定的,作為語言標準給出购对,稍后本文會再做介紹猾昆。

比如c++中,

#include <iostream>
int main() {
    int a = 1;
    int &b = a;    //c++中的引用可以使用在所有的類型上
    b = 2;
    printf("a = %d, b = %d\n", a, b);    //輸出結果為:a = 2, b = 2
}

兩者有什么不同

辨別value type骡苞,最基本和最有效的方法是觀察它的拷貝行為--賦值垂蜗、初始化、參數(shù)傳遞等帶來的影響解幽,即通過內存數(shù)據(jù)拷貝 創(chuàng)建 一個獨立的實例(instance)贴见。

// Value type example
struct S { var data: Int = -1 }
var a = S()
var b = a                        // a is copied to b
a.data = 42                        // Changes a, not b
println("\(a.data), \(b.data)")    // prints "42, -1"

拷貝引用則不同,它的行為類似于創(chuàng)建了一個指針躲株,原來在內存中的數(shù)據(jù)依然保持一份拷貝片部。因而改變其中某一個變量的值也會影響其他變量,即產(chǎn)生副作用徘溢。

// Reference type example
class C { var data: Int = -1 }
var x = C()                      // 建立一個對象的引用x
var y = x                        // 建立對象的另一個引用y
x.data = 42                        // changes the instance referred to by x (and y)
println("\(x.data), \(y.data)")    // prints "42, 42"

可以看出這個例子和之前c++引用產(chǎn)生了同樣的效果吞琐。

請在保證安全的情況下修改變量值

開發(fā)軟件捆探,其中最重要的要求(之一)是程序的正確性然爆,一種保證是來自于編程語言本身,另一種當然是來自程序員黍图。那么程序員在寫代碼的過程中如何選擇使用的類型呢曾雕?value type和reference type相比較,選擇使用value type可以使你的程序直觀上更加符合邏輯助被。如果所有的變量在內存中都有自己單獨的一塊區(qū)域剖张,你就大可不必擔心程序的其他部分在無意中修改這些變量的值。這在多線程環(huán)境中尤其重要揩环,因為不同的線程會同時修改變量的值搔弄。如果變量是reference類型就十分危險,這使你的程序出現(xiàn)不可預期的結果丰滑,調試起來也非常困難顾犹。

更理想的一種情況是,你聲明和使用的變量是只讀(不可寫)的,就不會出現(xiàn)數(shù)據(jù)不一致的情況發(fā)生炫刷。實際上擎宝,在沒有變量值改動的程序中,變量是type的或者reference的對程序的行為沒有任何影響浑玛。這時候reference內存占用少绍申,當然是優(yōu)先使用reference。

如何選擇

使用value type顾彰,當:

  • 你想要變量之間的賦值隱含數(shù)據(jù)拷貝极阅,使變量之間的狀態(tài)完全獨立。
  • 代碼中的數(shù)據(jù)操作分布在多個進程拘央。

使用reference type涂屁,當:

  • 創(chuàng)建共享和允許修改的狀態(tài)。

很多人其實有一種對編程語言的誤解灰伟,認為在語言層面約束越少的語言越好拆又,這樣就可以很容易實現(xiàn)想要的功能。但是靈活性帶來的壞處更加容易被人忽視栏账。交給程序員處理的事情越多帖族,導致寫出來的代碼更加容易產(chǎn)生bug,代碼可閱讀性大大降低挡爵,同時增加重構的難度竖般。

而swift在這方面給出了比較嚴格的限制,在swift中茶鹃,struct, Array, String, 和 Dictionary 都是value type涣雕,它們的行為就像c語言中的int,你幾乎不用做任何額外的工作闭翩,比如為了防止代碼的其余部分對數(shù)據(jù)進行修改而顯式地為變量分配額外的內存空間挣郭,這些繁瑣的過程都會因為swift中變量的value type的屬性,而交給編譯器去做疗韵。更加重要的是兑障,你可以很放心的將變量的數(shù)據(jù)拷貝交給其他進程進行操作而不用擔心同步問題。這些語言層面的約束都是為了程序員可以寫出可預測的代碼蕉汪。作為對比流译,下文介紹c++是怎么做的。

c++類型行為的不一致性

碰巧在微信中看到的一篇文章:C++ 之 stl::string 寫時拷貝導致的問題者疤。c++在語言標準上允許不同的數(shù)據(jù)拷貝機制福澡,聯(lián)系到本文的概念,即c++中的類型是value type還是reference type取決于編譯器的實現(xiàn)驹马。當語言標準容忍實現(xiàn)的靈活性時革砸,雖然多數(shù)時候是為了優(yōu)化性能眯搭,但是帶來的問題似乎更加嚴重--導致程序的運行結果不同于預期。

參考文章

  1. Value and Reference Types
  2. Why java has "String" type and not "string"? - Stack Overflow
  3. If immutable objects are good, why do people keep creating mutable objects?
  4. C++之stl::string寫時拷貝導致的問題
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末业岁,一起剝皮案震驚了整個濱河市鳞仙,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌笔时,老刑警劉巖棍好,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異允耿,居然都是意外死亡借笙,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門较锡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來业稼,“玉大人,你說我怎么就攤上這事蚂蕴〉蜕ⅲ” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵骡楼,是天一觀的道長熔号。 經(jīng)常有香客問我,道長鸟整,這世上最難降的妖魔是什么引镊? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮篮条,結果婚禮上弟头,老公的妹妹穿的比我還像新娘。我一直安慰自己涉茧,他們只是感情好赴恨,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著降瞳,像睡著了一般嘱支。 火紅的嫁衣襯著肌膚如雪蚓胸。 梳的紋絲不亂的頭發(fā)上挣饥,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音沛膳,去河邊找鬼扔枫。 笑死,一個胖子當著我的面吹牛锹安,可吹牛的內容都是我干的短荐。 我是一名探鬼主播倚舀,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼忍宋!你這毒婦竟也來了痕貌?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤糠排,失蹤者是張志新(化名)和其女友劉穎舵稠,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體入宦,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡哺徊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了乾闰。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片落追。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖涯肩,靈堂內的尸體忽然破棺而出轿钠,到底是詐尸還是另有隱情,我是刑警寧澤病苗,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布谣膳,位于F島的核電站,受9級特大地震影響铅乡,放射性物質發(fā)生泄漏继谚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一阵幸、第九天 我趴在偏房一處隱蔽的房頂上張望花履。 院中可真熱鬧,春花似錦挚赊、人聲如沸诡壁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽妹卿。三九已至,卻和暖如春蔑鹦,著一層夾襖步出監(jiān)牢的瞬間夺克,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工嚎朽, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留铺纽,地道東北人。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓哟忍,卻偏偏與公主長得像狡门,于是被迫代替她去往敵國和親陷寝。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內容