和其他語言不同的是胸嘁,Swift不需要為自定義的類和結(jié)構(gòu)體創(chuàng)建接口和實(shí)現(xiàn)文件。只需要?jiǎng)?chuàng)建單一文件用來創(chuàng)建類和結(jié)構(gòu)體群井,其他的外部接口的代碼系統(tǒng)會(huì)自動(dòng)生成毫胜。
通常一個(gè)類的實(shí)例會(huì)稱為對(duì)象书斜。相比于其他語言,Swift中的類和結(jié)構(gòu)體更加密切荐吉,這一章中討論的大部分功能都是可以用在類和結(jié)構(gòu)體上凝化,所以,這里主要使用實(shí)例而不是對(duì)象(這句話不是很理解)瞧哟。
類和結(jié)構(gòu)體的對(duì)比(Comparing Classes and Structures)
類和結(jié)構(gòu)體在Swift中有很多相同點(diǎn):
- 定義屬性來存儲(chǔ)值
- 定義方法來提供功能
- 定義下標(biāo)來提供通過下標(biāo)語法來訪問其實(shí)例所包含的值
- 定義構(gòu)造器(Initializer)來生成初始化值
- 在默認(rèn)實(shí)現(xiàn)的功能的基礎(chǔ)上進(jìn)行擴(kuò)展
- 實(shí)現(xiàn)協(xié)議來提供某種標(biāo)準(zhǔn)功能
和結(jié)構(gòu)體相比勤揩,類多了一些附加功能:
- 繼承允許一個(gè)類繼承另一個(gè)類的特性
- 類型轉(zhuǎn)換允許在運(yùn)行時(shí)檢查和解釋一個(gè)類實(shí)例的類型
- 析構(gòu)器(Deinitializer)允許一個(gè)類實(shí)例釋放任何其所分配的資源
- 引用計(jì)數(shù)允許對(duì)一個(gè)類的多次引用
注意
結(jié)構(gòu)體總是通過復(fù)制的方式在代碼中傳遞秘蛔,所以并不使用引用計(jì)數(shù)傍衡。
定義語法(Definition Syntax)
類和結(jié)構(gòu)體有相似的定義語法:
class SomeClass {
//類的主體放在這
}
struct SomeStructure {
//結(jié)構(gòu)體的主體放在這
}
類和結(jié)構(gòu)體實(shí)例(Class and Structure Instances)
生成類和結(jié)構(gòu)體的實(shí)例的方法也非常相似:
結(jié)構(gòu)體和類都使用構(gòu)造器語法來生成新的實(shí)例蛙埂。構(gòu)造器語法最簡(jiǎn)單的形式就是在后面跟一對(duì)空白的括號(hào)遮糖,這樣生成的實(shí)例的屬性都會(huì)被初始化為默認(rèn)值。
訪問屬性(Accessing Properties)
可以通過點(diǎn)語法來訪問實(shí)例的屬性:
不像 OC 屡江,Swift 允許直接設(shè)置結(jié)構(gòu)體屬性的子屬性惩嘉。
結(jié)構(gòu)體類型的成員逐一構(gòu)造器(Memberwise Initializers for Structure Types)
所有的結(jié)構(gòu)體都有一個(gè)自動(dòng)生成的成員逐一構(gòu)造器踢故,用來初始化結(jié)構(gòu)體實(shí)例中的成員屬性:
let vga = Resolution(width: 640, height: 480)
與結(jié)構(gòu)體不同,類的實(shí)例沒有默認(rèn)的成員逐一構(gòu)造器臊诊。
結(jié)構(gòu)體和枚舉是值類型(Structures and Enumerations Are Value Types)
值類型被賦予給一個(gè)常量(變量)或傳遞給一個(gè)函數(shù)的時(shí)候斜脂,其值會(huì)被拷貝。
在之前的文章里玷或,已經(jīng)使用了大量的值類型片任。事實(shí)上,在Swift中的所有基礎(chǔ)類型都是值類型:整型对供、浮點(diǎn)型、布爾型鹅髓、字符串京景、數(shù)組、字典醒串,并且底層都是以結(jié)構(gòu)體的形式實(shí)現(xiàn)的。
所有的結(jié)構(gòu)體和枚舉在Swift中都是值類型仰挣,這就意味著任何創(chuàng)建的結(jié)構(gòu)體和枚舉缠沈,以及實(shí)例中包含的任何值類型屬性,都是通過復(fù)制在代碼中傳遞的。
枚舉也是相同的準(zhǔn)則:
類是引用類型(Classes Are Reference Types)
和值類型不同禽篱,引用類型在被賦予到一個(gè)變量(常量)或被傳遞到一個(gè)函數(shù)時(shí)馍惹,值不會(huì)被拷貝。所以悼吱,引用的是已經(jīng)存在的實(shí)例本身而不是其拷貝:
注意
雖然 tenEighty 和 alsoTenEighty 被聲名為常量良狈,但是你依舊可以改變其屬性,這就是因?yàn)檫@兩個(gè)常量的值并沒有改變遇西。它們只是對(duì)VideoMode實(shí)例的引用严嗜。
恒等運(yùn)算符(Identity Operators)
因?yàn)轭愂且妙愋停跃涂赡艹霈F(xiàn)多個(gè)常量(變量)同時(shí)引用一個(gè)類實(shí)例茄蚯。如果能判斷兩個(gè)常量(變量)是否是引用同一個(gè)實(shí)例的話就很有用了睦优,所以Swift就出現(xiàn)了這么兩個(gè)恒等運(yùn)算符:
- 等價(jià)于 (===)
- 不等價(jià)于 (!==)
注意
『等價(jià)于』(===)與『等于』(==)是不一樣的:
- 『等價(jià)于』的意思是兩個(gè)類類型的常量(變量)是否引用同一個(gè)實(shí)例刨秆。
- 『等于』的意思是兩個(gè)實(shí)例的值是否 "相等",判斷的時(shí)候應(yīng)該遵循設(shè)計(jì)這定義的評(píng)判標(biāo)準(zhǔn)尸执。
當(dāng)在定義自定義類和結(jié)構(gòu)體的時(shí)候,是有責(zé)任來判斷兩個(gè)實(shí)例 "相等" 的標(biāo)準(zhǔn)的如失。
指針(Pointers)
像C, C++, OC中褪贵,指針都是用來引用內(nèi)存中的地址。一個(gè)引用某個(gè)引用類型實(shí)例的常量(變量)脆丁,與C語言中的指針類似,但是并不直接指向某個(gè)內(nèi)存地址跟压,同時(shí)也不需要星號(hào)(*)來表明你在創(chuàng)建一個(gè)引用歼培。
類和結(jié)構(gòu)體的選擇(Choosing Between Classes and Structures)
因?yàn)榻Y(jié)構(gòu)體實(shí)例是通過值傳遞,而類實(shí)例是通過引用傳遞查剖,顯而易見噪窘,這兩種類型針對(duì)這不同的任務(wù)。
一般情況下无切,滿足一條以上的條件是丐枉,會(huì)考慮構(gòu)建結(jié)構(gòu)體:
- 數(shù)據(jù)結(jié)構(gòu)主要的目的就是封裝一些簡(jiǎn)單的數(shù)據(jù)值。
- 有理由預(yù)計(jì)該數(shù)據(jù)結(jié)構(gòu)的實(shí)例在被賦值或者傳遞的時(shí)候籍嘹,封裝的數(shù)據(jù)是要進(jìn)行拷貝而不是引用弯院。
- 該數(shù)據(jù)結(jié)構(gòu)中儲(chǔ)存的值類型屬性也應(yīng)該被拷貝,而不是引用听绳。
- 該數(shù)據(jù)結(jié)構(gòu)不需要去繼承另一個(gè)既有類型的屬性或者行為椅挣。
舉幾個(gè)小??來說一下適合結(jié)構(gòu)體的情況:
- 集合圖像的尺寸塔拳,封裝了 width 和 height 屬性峡竣,兩屬性的類型都是 Double。
- 在一定范圍內(nèi)的路徑颂碧,封裝一個(gè) start 屬性和一個(gè) length 屬性类浪,兩屬性的類型都是 Int。
- 一個(gè)點(diǎn)在三維坐標(biāo)系中个曙,封裝 x, y, z 屬性受楼,均為 Double呼寸。
在其他的情況下,定義類河狐,生成一個(gè)類的實(shí)例瑟捣,并通過引用來管理和傳遞。也就是說迈套,在絕大部分的自定義數(shù)據(jù)構(gòu)造都應(yīng)該是類,而并不是結(jié)構(gòu)體踱蛀。
字符串贵白、數(shù)組和字典的賦值和復(fù)制行為(Assignment and Copy Behavior for Strings, Arrays, and Dictionaries)
Swift中這些類型都是結(jié)構(gòu)體的形式表現(xiàn)出來禁荒。但是在 OC 中,NSString, NSArray 和 NSDictionary 都是以類的形式表現(xiàn)出來的呛伴,所以它們?cè)谫x值或被傳入函數(shù)或方法時(shí)谒所,不會(huì)發(fā)生值拷貝百炬,而是傳遞污它。
注意
以上是對(duì)字符串、數(shù)組衫贬、字典的 "拷貝" 行為的描述固惯。在你的代碼中,拷貝行為看起來似乎總會(huì)發(fā)生葬毫。然而贴捡,Swift 在幕后只在絕對(duì)必要時(shí)才執(zhí)行實(shí)際的拷貝。Swift 管理所有的值拷貝以確保性能最優(yōu)化烂斋,所以你沒必要去回避賦值來保證性能最優(yōu)化。