在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ iOS/ Swift 里的值類型與引用類型
特性(Attributes)
Access Control 權(quán)限控制的黑與白
基本運(yùn)算符(Basic Operators)
基礎(chǔ)部分(The Basics)
閉包(Closures)
擴(kuò)展
泛型參數(shù)(Generic Parameters and Arguments)
訪問(wèn)控制和 protected
語(yǔ)句(Statements)
模式(Patterns)
WWDC 里面的那個(gè)“大炮打氣球”
關(guān)于語(yǔ)言參考(About the Language Reference)
語(yǔ)法總結(jié)(Summary of the Grammar)
嵌套類型
類型(Types)
Swift 初見(jiàn)(A Swift Tour)
泛型
枚舉(Enumerations)
高級(jí)運(yùn)算符
繼承
析構(gòu)過(guò)程
關(guān)于 Swift(About Swift)
訪問(wèn)控制
類和結(jié)構(gòu)體
內(nèi)存安全
Swift 與 C 語(yǔ)言指針友好合作
協(xié)議
屬性(Properties)
可選類型完美解決占位問(wèn)題
錯(cuò)誤處理
字符串和字符(Strings and Characters)
聲明(Declarations)
自動(dòng)引用計(jì)數(shù)
Swift 里的值類型與引用類型
表達(dá)式(Expressions)
Swift 文檔修訂歷史
造個(gè)類型不是夢(mèng)-白話 Swift 類型創(chuàng)建
歡迎使用 Swift
詞法結(jié)構(gòu)(Lexical Structure)
集合類型(Collection Types)
下標(biāo)
方法(Methods)
可選鏈?zhǔn)秸{(diào)用
版本兼容性
類型轉(zhuǎn)換
構(gòu)造過(guò)程
The Swift Programming Language 中文版
函數(shù)(Functions)
Swift 教程
控制流(Control Flow)

Swift 里的值類型與引用類型


翻譯:老碼團(tuán)隊(duì)翻譯組-Arya 校對(duì):老碼團(tuán)隊(duì)翻譯組-Jame

本頁(yè)包含內(nèi)容:

Swift 里面的類型分為兩種:

  • 值類型(Value Types):每個(gè)實(shí)例都保留了一分獨(dú)有的數(shù)據(jù)拷貝,一般以結(jié)構(gòu)體 (struct)枚舉(enum) 或者 元組(tuple)的形式出現(xiàn)。
  • 引用類型(Reference Type):每個(gè)實(shí)例共享同一份數(shù)據(jù)來(lái)源,一般以 類(class)的形式出現(xiàn)。

在這篇博文里面,我們會(huì)介紹兩種類型各自的優(yōu)點(diǎn),以及應(yīng)該怎么選擇使用。

值類型與引用類型的區(qū)別

值類型和引用類型最基本的分別在復(fù)制之后的結(jié)果。當(dāng)一個(gè)值類型被復(fù)制的時(shí)候,相當(dāng)于創(chuàng)造了一個(gè)完全獨(dú)立的實(shí)例,這個(gè)實(shí)例保有屬于自己的獨(dú)有數(shù)據(jù),數(shù)據(jù)不會(huì)受到其他實(shí)例的數(shù)據(jù)變化影響:

    // 下面是一個(gè)值類型的例子
    struct S { var data: Int = -1 }
    var a = S()
    var b = a                           // b 是 a 的拷貝
    a.data = 42                         // 更改 a 的數(shù)據(jù),b 的不受影響
    println("\(a.data), \(b.data)")     // 輸出結(jié)果 "42, -1"

值類型就好像身份證復(fù)印件一樣,復(fù)印出來(lái)之后,修改原件上面的內(nèi)容,復(fù)印件上的內(nèi)容不會(huì)變。

另一方面,復(fù)制一個(gè)引用類型的時(shí)候,實(shí)際上是默默地創(chuàng)造了一個(gè)共享的實(shí)例分身,兩者是共用一套數(shù)據(jù)。因此修改其中任何一個(gè)實(shí)例的數(shù)據(jù),也會(huì)影響到另外那個(gè)。

    // 下面是一個(gè)引用類型的例子
    class C { var data: Int = -1 }
    var x = C()
    var y = x                           // y 是 x 的拷貝
    x.data = 42                         // 更改 x 的數(shù)據(jù),等于同時(shí)修改了 y
    println("\(x.data), \(y.data)")     // 輸出結(jié)果 "42, 42"

Mutation(修改)在安全中扮演的角色

值類型較引用類型來(lái)說(shuō),會(huì)讓你更容易在大量代碼中理清狀況。如果你總是得到一個(gè)獨(dú)立的拷貝出來(lái)的實(shí)例,你就可以放心它不會(huì)被你 app 里面的其他部分代碼默默地修改。這在多線程的環(huán)境里面是尤為重要的,因?yàn)榱硗庖粋€(gè)線程可能會(huì)在暗地里修改你的數(shù)據(jù)。因此可能會(huì)造成嚴(yán)重的程序錯(cuò)誤,這在調(diào)試過(guò)程中非常難以排除。

由于差別主要在于修改數(shù)據(jù)的后果,那么當(dāng)實(shí)例的數(shù)據(jù)只讀,不存在需要更改的情況下,用哪種類型都是沒(méi)有分別的。

你可能在想,有的時(shí)候我可能也需要一個(gè)完全不變的類。這樣使用 Cocoa NSObject 對(duì)象的時(shí)候會(huì)比較容易,又可以保留值語(yǔ)義的好處。在今天,你可以通過(guò)只使用不可變的存儲(chǔ)屬性,和避開任何可以修改狀態(tài)的 API,用 Swift 寫出一個(gè)不可變類 (immutable class)。實(shí)際上,很多基本的 Cocoa 類,例如 NSURL,都是設(shè)計(jì)成不可變類的。然而,Swift 語(yǔ)言目前只強(qiáng)制 structenum 這種值類型的不可變性,對(duì)類這種引用類型則沒(méi)有。(例如還不支持強(qiáng)制將子類的限制為不可變類)

如何選擇類型?

所以當(dāng)我們想要建立一個(gè)新的類型的時(shí)候,怎么決定用值類型還是引用類型呢?當(dāng)你使用 Cocoa 框架的時(shí)候,很多 API 都要通過(guò) NSObject 的子類使用,所以這時(shí)候必須要用到引用類型 class。在其他情況下,有下面幾個(gè)準(zhǔn)則:

  • 什么時(shí)候該用值類型

    • 要用==運(yùn)算符來(lái)比較實(shí)例的數(shù)據(jù)時(shí)
    • 你希望那個(gè)實(shí)例的拷貝能保持獨(dú)立的狀態(tài)時(shí)
    • 數(shù)據(jù)會(huì)被多個(gè)線程使用時(shí)
  • 什么時(shí)候該用引用類型(class)
    • 要用==運(yùn)算符來(lái)比較實(shí)例身份的時(shí)候
    • 你希望有創(chuàng)建一個(gè)共享的、可變對(duì)象的時(shí)候

在 Swift 里面,數(shù)組(Array)、字符串(String)、字典(Dictionary)都屬于值類型。它們就像 C 語(yǔ)言里面簡(jiǎn)單的 int 值,是一個(gè)個(gè)獨(dú)立的數(shù)據(jù)個(gè)體。你不需要花任何功夫來(lái)防范其他代碼在暗地里修改它們。更重要的是,你可以在線程之間安全的傳遞變量,而不需要特地去同步。在 Swift 高安全性的精神下,這個(gè)模式會(huì)幫助你用 Swift 寫出更可控的代碼。


本章節(jié)不是老碼的原創(chuàng),老碼認(rèn)真的閱讀了蘋果的官方博客,且自己的練習(xí)總結(jié),如果小伙伴們費(fèi)了吃奶的勁還是看不懂,請(qǐng)找度娘谷歌,還是看不懂請(qǐng)到老碼官方微博咆哮。

本文由翻譯自 Apple Swift Blog :Value and Reference Types