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

鍍金池/ 教程/ iOS/ 類(lèi)型(Types)
特性(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)
嵌套類(lèi)型
類(lèi)型(Types)
Swift 初見(jiàn)(A Swift Tour)
泛型
枚舉(Enumerations)
高級(jí)運(yùn)算符
繼承
析構(gòu)過(guò)程
關(guān)于 Swift(About Swift)
訪問(wèn)控制
類(lèi)和結(jié)構(gòu)體
內(nèi)存安全
Swift 與 C 語(yǔ)言指針友好合作
協(xié)議
屬性(Properties)
可選類(lèi)型完美解決占位問(wèn)題
錯(cuò)誤處理
字符串和字符(Strings and Characters)
聲明(Declarations)
自動(dòng)引用計(jì)數(shù)
Swift 里的值類(lèi)型與引用類(lèi)型
表達(dá)式(Expressions)
Swift 文檔修訂歷史
造個(gè)類(lèi)型不是夢(mèng)-白話(huà) Swift 類(lèi)型創(chuàng)建
歡迎使用 Swift
詞法結(jié)構(gòu)(Lexical Structure)
集合類(lèi)型(Collection Types)
下標(biāo)
方法(Methods)
可選鏈?zhǔn)秸{(diào)用
版本兼容性
類(lèi)型轉(zhuǎn)換
構(gòu)造過(guò)程
The Swift Programming Language 中文版
函數(shù)(Functions)
Swift 教程
控制流(Control Flow)

類(lèi)型(Types)


1.0 翻譯:lyuka 校對(duì):numbbbbb, stanzhai

2.0 翻譯+校對(duì):EudeMorgen

2.1 翻譯:mmoaay

4.1 翻譯+校對(duì):mylittleswift

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

Swift 語(yǔ)言存在兩種類(lèi)型:命名型類(lèi)型和復(fù)合型類(lèi)型。命名型類(lèi)型是指定義時(shí)可以給定名字的類(lèi)型。命名型類(lèi)型包括類(lèi)、結(jié)構(gòu)體、枚舉和協(xié)議。比如,一個(gè)用戶(hù)定義的類(lèi) MyClass 的實(shí)例擁有類(lèi)型 MyClass。除了用戶(hù)定義的命名型類(lèi)型,Swift 標(biāo)準(zhǔn)庫(kù)也定義了很多常用的命名型類(lèi)型,包括那些表示數(shù)組、字典和可選值的類(lèi)型。

那些通常被其它語(yǔ)言認(rèn)為是基本或原始的數(shù)據(jù)型類(lèi)型,比如表示數(shù)字、字符和字符串的類(lèi)型,實(shí)際上就是命名型類(lèi)型,這些類(lèi)型在 Swift 標(biāo)準(zhǔn)庫(kù)中是使用結(jié)構(gòu)體來(lái)定義和實(shí)現(xiàn)的。因?yàn)樗鼈兪敲皖?lèi)型,因此你可以按照 擴(kuò)展擴(kuò)展聲明 中討論的那樣,聲明一個(gè)擴(kuò)展來(lái)增加它們的行為以滿(mǎn)足你程序的需求。

復(fù)合型類(lèi)型是沒(méi)有名字的類(lèi)型,它由 Swift 本身定義。Swift 存在兩種復(fù)合型類(lèi)型:函數(shù)類(lèi)型和元組類(lèi)型。一個(gè)復(fù)合型類(lèi)型可以包含命名型類(lèi)型和其它復(fù)合型類(lèi)型。例如,元組類(lèi)型 (Int, (Int, Int)) 包含兩個(gè)元素:第一個(gè)是命名型類(lèi)型 Int,第二個(gè)是另一個(gè)復(fù)合型類(lèi)型 (Int, Int)。

你可以在命名型類(lèi)型和復(fù)合型類(lèi)型使用小括號(hào)。但是在類(lèi)型旁加小括號(hào)沒(méi)有任何作用。舉個(gè)例子,(Int) 等同于 Int。

本節(jié)討論 Swift 語(yǔ)言本身定義的類(lèi)型,并描述 Swift 中的類(lèi)型推斷行為。

類(lèi)型語(yǔ)法

類(lèi)型數(shù)組類(lèi)型 類(lèi)型字典類(lèi)型 類(lèi)型函數(shù)類(lèi)型 類(lèi)型類(lèi)型標(biāo)識(shí) 類(lèi)型元組類(lèi)型 類(lèi)型可選類(lèi)型 類(lèi)型隱式解析可選類(lèi)型 類(lèi)型協(xié)議合成類(lèi)型 類(lèi)型元型類(lèi)型 類(lèi)型任意類(lèi)型 類(lèi)型自身類(lèi)型 類(lèi)型(類(lèi)型)

類(lèi)型注解

類(lèi)型注解顯式地指定一個(gè)變量或表達(dá)式的值。類(lèi)型注解始于冒號(hào) : 終于類(lèi)型,比如下面兩個(gè)例子:

let someTuple: (Double, Double) = (3.14159, 2.71828)
func someFunction(a: Int) { /* ... */ }

在第一個(gè)例子中,表達(dá)式 someTuple 的類(lèi)型被指定為 (Double, Double)。在第二個(gè)例子中,函數(shù) someFunction 的參數(shù) a 的類(lèi)型被指定為 Int。

類(lèi)型注解可以在類(lèi)型之前包含一個(gè)類(lèi)型特性的可選列表。

類(lèi)型注解語(yǔ)法

類(lèi)型注解: 特性列表可選 輸入輸出參數(shù)可選 類(lèi)型

類(lèi)型標(biāo)識(shí)符

類(lèi)型標(biāo)識(shí)符引用命名型類(lèi)型,還可引用命名型或復(fù)合型類(lèi)型的別名。

大多數(shù)情況下,類(lèi)型標(biāo)識(shí)符引用的是與之同名的命名型類(lèi)型。例如類(lèi)型標(biāo)識(shí)符 Int 引用命名型類(lèi)型 Int,同樣,類(lèi)型標(biāo)識(shí)符 Dictionary<String, Int> 引用命名型類(lèi)型 Dictionary<String, Int>。

在兩種情況下類(lèi)型標(biāo)識(shí)符不引用同名的類(lèi)型。情況一,類(lèi)型標(biāo)識(shí)符引用的是命名型或復(fù)合型類(lèi)型的類(lèi)型別名。比如,在下面的例子中,類(lèi)型標(biāo)識(shí)符使用 Point 來(lái)引用元組 (Int, Int)

typealias Point = (Int, Int)
let origin: Point = (0, 0)

情況二,類(lèi)型標(biāo)識(shí)符使用點(diǎn)語(yǔ)法(.)來(lái)表示在其它模塊或其它類(lèi)型嵌套內(nèi)聲明的命名型類(lèi)型。例如,下面例子中的類(lèi)型標(biāo)識(shí)符引用在 ExampleModule 模塊中聲明的命名型類(lèi)型 MyType

var someValue: ExampleModule.MyType

類(lèi)型標(biāo)識(shí)符語(yǔ)法

類(lèi)型標(biāo)識(shí)符類(lèi)型名稱(chēng) 泛型參數(shù)子句可選 | 類(lèi)型名稱(chēng) 泛型參數(shù)子句可選 . 類(lèi)型標(biāo)識(shí)符 類(lèi)型名稱(chēng)標(biāo)識(shí)符

元組類(lèi)型

元組類(lèi)型是使用括號(hào)括起來(lái)的零個(gè)或多個(gè)類(lèi)型,類(lèi)型間用逗號(hào)隔開(kāi)。

你可以使用元組類(lèi)型作為一個(gè)函數(shù)的返回類(lèi)型,這樣就可以使函數(shù)返回多個(gè)值。你也可以命名元組類(lèi)型中的元素,然后用這些名字來(lái)引用每個(gè)元素的值。元素的名字由一個(gè)標(biāo)識(shí)符緊跟一個(gè)冒號(hào) (:) 組成。函數(shù)和多返回值 章節(jié)里有一個(gè)展示上述特性的例子。

當(dāng)一個(gè)元組類(lèi)型的元素有名字的時(shí)候,這個(gè)名字就是類(lèi)型的一部分。

var someTuple = (top: 10, bottom: 12)  // someTuple 的類(lèi)型為 (top: Int, bottom: Int)
someTuple = (top: 4, bottom: 42) // 正確:命名類(lèi)型匹配
someTuple = (9, 99)              // 正確:命名類(lèi)型被自動(dòng)推斷
someTuple = (left: 5, right: 5)  // 錯(cuò)誤:命名類(lèi)型不匹配

所有的元組類(lèi)型都包含兩個(gè)及以上元素, 除了 Void。Void 是空元組類(lèi)型 () 的別名。

元組類(lèi)型語(yǔ)法

元組類(lèi)型( 元組類(lèi)型元素列表 可選 ) 元組類(lèi)型元素列表元組類(lèi)型元素 | 元組類(lèi)型元素 , 元組類(lèi)型元素列表 元組類(lèi)型元素元素名 類(lèi)型注解 | 類(lèi)型 元素名標(biāo)識(shí)符

函數(shù)類(lèi)型

函數(shù)類(lèi)型表示一個(gè)函數(shù)、方法或閉包的類(lèi)型,它由參數(shù)類(lèi)型和返回值類(lèi)型組成,中間用箭頭(->)隔開(kāi):

參數(shù)類(lèi)型 -> 返回值類(lèi)型

參數(shù)類(lèi)型是由逗號(hào)間隔的類(lèi)型列表。由于參數(shù)類(lèi)型和返回值類(lèi)型可以是元組類(lèi)型,所以函數(shù)類(lèi)型支持多參數(shù)與多返回值的函數(shù)與方法。

你可以對(duì)函數(shù)參數(shù) () -> T(其中 T 是任何類(lèi)型)使用 autoclosure 特性。這會(huì)自動(dòng)將參數(shù)表達(dá)式轉(zhuǎn)化為閉包,表達(dá)式的結(jié)果即閉包返回值。這從語(yǔ)法結(jié)構(gòu)上提供了一種便捷:延遲對(duì)表達(dá)式的求值,直到其值在函數(shù)體中被調(diào)用。以自動(dòng)閉包做為參數(shù)的函數(shù)類(lèi)型的例子詳見(jiàn) 自動(dòng)閉包

函數(shù)類(lèi)型可以擁有一個(gè)可變長(zhǎng)參數(shù)作為參數(shù)類(lèi)型中的最后一個(gè)參數(shù)。從語(yǔ)法角度上講,可變長(zhǎng)參數(shù)由一個(gè)基礎(chǔ)類(lèi)型名字緊隨三個(gè)點(diǎn)(...)組成,如 Int...??勺冮L(zhǎng)參數(shù)被認(rèn)為是一個(gè)包含了基礎(chǔ)類(lèi)型元素的數(shù)組。即 Int... 就是 [Int]。關(guān)于使用可變長(zhǎng)參數(shù)的例子,請(qǐng)參閱 可變參數(shù)。

為了指定一個(gè) in-out 參數(shù),可以在參數(shù)類(lèi)型前加 inout 前綴。但是你不可以對(duì)可變長(zhǎng)參數(shù)或返回值類(lèi)型使用 inout。關(guān)于這種參數(shù)的詳細(xì)講解請(qǐng)參閱 輸入輸出參數(shù)。

如果一個(gè)函數(shù)類(lèi)型只有一個(gè)形式參數(shù)而且形式參數(shù)的類(lèi)型是元組類(lèi)型,那么元組類(lèi)型在寫(xiě)函數(shù)類(lèi)型的時(shí)候必須用圓括號(hào)括起來(lái)。比如說(shuō),((Int, Int)) -> Void 是接收一個(gè)元組 (Int, Int) 作為形式參數(shù)的函數(shù)的類(lèi)型。與此相反,不加括號(hào)的 (Int, Int) -> Void 是一個(gè)接收兩個(gè) Int 形式參數(shù)并且不返回任何值的函數(shù)的類(lèi)型。相似地,因?yàn)?Void 是空元組類(lèi)型 () 的別名, 函數(shù)類(lèi)型 (Void)-> Void 與一個(gè)空元組的變量的函數(shù)類(lèi)型 (()) -> () 是一樣的。但這些類(lèi)型和無(wú)變量的函數(shù)類(lèi)型 () -> () 是不一樣的。

函數(shù)和方法中的變量名并不是函數(shù)類(lèi)型的一部分。例如:

func someFunction(left: Int, right: Int) {}
func anotherFunction(left: Int, right: Int) {}
func functionWithDifferentLabels(top: Int, bottom: Int) {}

var f = someFunction // 函數(shù) f 的類(lèi)型為 (Int, Int) -> Void, 而不是 (left: Int, right: Int) -> Void.
f = anotherFunction              // 正確
f = functionWithDifferentLabels  // 正確

func functionWithDifferentArgumentTypes(left: Int, right: String) {}
func functionWithDifferentNumberOfArguments(left: Int, right: Int, top: Int) {}

f = functionWithDifferentArgumentTypes     // 錯(cuò)誤
f = functionWithDifferentNumberOfArguments // 錯(cuò)誤

由于變量標(biāo)簽不是函數(shù)類(lèi)型的一部分,你可以在寫(xiě)函數(shù)類(lèi)型的時(shí)候省略它們。

var operation: (lhs: Int, rhs: Int) -> Int      // 錯(cuò)誤
var operation: (_ lhs: Int, _ rhs: Int) -> Int  // 正確
var operation: (Int, Int) -> Int                // 正確

如果一個(gè)函數(shù)類(lèi)型包涵多個(gè)箭頭(->),那么函數(shù)類(lèi)型將從右向左進(jìn)行組合。例如,函數(shù)類(lèi)型 Int -> Int -> Int 可以理解為 Int -> (Int -> Int),也就是說(shuō),該函數(shù)類(lèi)型的參數(shù)為 Int 類(lèi)型,其返回類(lèi)型是一個(gè)參數(shù)類(lèi)型為 Int,返回類(lèi)型為 Int 的函數(shù)類(lèi)型。

函數(shù)類(lèi)型若要拋出錯(cuò)誤就必須使用 throws 關(guān)鍵字來(lái)標(biāo)記,若要重拋錯(cuò)誤則必須使用 rethrows 關(guān)鍵字來(lái)標(biāo)記。throws 關(guān)鍵字是函數(shù)類(lèi)型的一部分,非拋出函數(shù)是拋出函數(shù)函數(shù)的一個(gè)子類(lèi)型。因此,在使用拋出函數(shù)的地方也可以使用不拋出函數(shù)。拋出和重拋函數(shù)的相關(guān)描述見(jiàn)章節(jié) 拋出函數(shù)與方法重拋函數(shù)與方法

對(duì)非逃逸閉包的限制

非逃逸閉包函數(shù)不能作為參數(shù)傳遞到另一個(gè)非逃逸閉包函數(shù)的參數(shù)。這樣的限制可以讓 Swift 在編譯時(shí)就完成更多的內(nèi)存訪問(wèn)沖突檢查, 而不是在運(yùn)行時(shí)。舉個(gè)例子:

let external: (Any) -> Void = { _ in () }
func takesTwoFunctions(first: (Any) -> Void, second: (Any) -> Void) {
    first(first)    // 錯(cuò)誤
    second(second)  // 錯(cuò)誤

    first(second)   // 錯(cuò)誤
    second(first)   // 錯(cuò)誤

    first(external) // 正確
    external(first) // 正確
}

在上面代碼里,takesTwoFunctions(first:second:) 的兩個(gè)參數(shù)都是函數(shù)。 它們都沒(méi)有標(biāo)記為 @escaping, 因此它們都是非逃逸的。

上述例子里的被標(biāo)記為“錯(cuò)誤”的四個(gè)函數(shù)調(diào)用會(huì)產(chǎn)生編譯錯(cuò)誤。因?yàn)榈谝粋€(gè)和第二個(gè)參數(shù)是非逃逸函數(shù),它們不能夠被當(dāng)作變量被傳遞到另一個(gè)非閉包函數(shù)參數(shù)。與此相反, 標(biāo)記“正確”的兩個(gè)函數(shù)不回產(chǎn)生編譯錯(cuò)誤。這些函數(shù)調(diào)用不會(huì)違反限制, 因?yàn)?外部(external) 不是 takesTwoFunctions(first:second:) 里的一個(gè)參數(shù)。

如果你需要避免這個(gè)限制, 標(biāo)記其中之一的參數(shù)為逃逸, 或者使用 withoutActuallyEscaping(_:do:) 函數(shù)臨時(shí)地轉(zhuǎn)換非逃逸函數(shù)的其中一個(gè)參數(shù)為逃逸函數(shù)。關(guān)于避免內(nèi)存訪問(wèn)沖突,可以參閱內(nèi)存安全。

函數(shù)類(lèi)型語(yǔ)法

函數(shù)類(lèi)型特性列表可選 函數(shù)類(lèi)型子句 throws可選 -> 類(lèi)型 函數(shù)類(lèi)型特性列表可選 函數(shù)類(lèi)型子句 rethrows- -> 類(lèi)型 函數(shù)類(lèi)型子句 → (-)- 函數(shù)類(lèi)型子句 → (函數(shù)類(lèi)型參數(shù)列表...-可選)- 函數(shù)類(lèi)型參數(shù)列表函數(shù)類(lèi)型參數(shù) | 函數(shù)類(lèi)型參數(shù), 函數(shù)類(lèi)型參數(shù)列表 函數(shù)類(lèi)型參數(shù)特性列表可選 輸入輸出參數(shù)可選 類(lèi)型 | 參數(shù)標(biāo)簽 類(lèi)型注解 參數(shù)標(biāo)簽標(biāo)識(shí)符

數(shù)組類(lèi)型

Swift 語(yǔ)言為標(biāo)準(zhǔn)庫(kù)中定義的 Array<Element> 類(lèi)型提供了如下語(yǔ)法糖:

[類(lèi)型]

換句話(huà)說(shuō),下面兩個(gè)聲明是等價(jià)的:

let someArray: Array<String> = ["Alex", "Brian", "Dave"]
let someArray: [String] = ["Alex", "Brian", "Dave"]

上面兩種情況下,常量 someArray 都被聲明為字符串?dāng)?shù)組。數(shù)組的元素也可以通過(guò)下標(biāo)訪問(wèn):someArray[0] 是指第 0 個(gè)元素 "Alex"。

你也可以嵌套多對(duì)方括號(hào)來(lái)創(chuàng)建多維數(shù)組,最里面的方括號(hào)中指明數(shù)組元素的基本類(lèi)型。比如,下面例子中使用三對(duì)方括號(hào)創(chuàng)建三維整數(shù)數(shù)組:

var array3D: [[[Int]]] = [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]

訪問(wèn)一個(gè)多維數(shù)組的元素時(shí),最左邊的下標(biāo)指向最外層數(shù)組的相應(yīng)位置元素。接下來(lái)往右的下標(biāo)指向第一層嵌入的相應(yīng)位置元素,依次類(lèi)推。這就意味著,在上面的例子中,array3D[0][[1, 2], [3, 4]],array3D[0][1][3, 4],array3D[0][1][1] 則是 4。

關(guān)于 Swift 標(biāo)準(zhǔn)庫(kù)中 Array 類(lèi)型的詳細(xì)討論,請(qǐng)參閱 數(shù)組。

數(shù)組類(lèi)型語(yǔ)法

數(shù)組類(lèi)型[ 類(lèi)型 ]

字典類(lèi)型

Swift 語(yǔ)言為標(biāo)準(zhǔn)庫(kù)中定義的 Dictionary<Key, Value> 類(lèi)型提供了如下語(yǔ)法糖:

[鍵類(lèi)型 : 值類(lèi)型]

換句話(huà)說(shuō),下面兩個(gè)聲明是等價(jià)的:

let someDictionary: [String: Int] = ["Alex": 31, "Paul": 39]
let someDictionary: Dictionary<String, Int> = ["Alex": 31, "Paul": 39]

上面兩種情況,常量 someDictionary 被聲明為一個(gè)字典,其中鍵為 String 類(lèi)型,值為 Int 類(lèi)型。

字典中的值可以通過(guò)下標(biāo)來(lái)訪問(wèn),這個(gè)下標(biāo)在方括號(hào)中指明了具體的鍵:someDictionary["Alex"] 返回鍵 Alex 對(duì)應(yīng)的值。如果鍵在字典中不存在的話(huà),則這個(gè)下標(biāo)返回 nil。

字典中鍵的類(lèi)型必須符合 Swift 標(biāo)準(zhǔn)庫(kù)中的 Hashable 協(xié)議。

關(guān)于 Swift 標(biāo)準(zhǔn)庫(kù)中 Dictionary 類(lèi)型的詳細(xì)討論,請(qǐng)參閱 字典

字典類(lèi)型語(yǔ)法

字典類(lèi)型[ 類(lèi)型 : 類(lèi)型 ]

可選類(lèi)型

Swift 定義后綴 ? 來(lái)作為標(biāo)準(zhǔn)庫(kù)中的定義的命名型類(lèi)型 Optional<Wrapped> 的語(yǔ)法糖。換句話(huà)說(shuō),下面兩個(gè)聲明是等價(jià)的:

var optionalInteger: Int?
var optionalInteger: Optional<Int>

在上述兩種情況下,變量 optionalInteger 都被聲明為可選整型類(lèi)型。注意在類(lèi)型和 ? 之間沒(méi)有空格。

類(lèi)型 Optional<Wrapped> 是一個(gè)枚舉,有兩個(gè)成員,nonesome(Wrapped),用來(lái)表示可能有也可能沒(méi)有的值。任意類(lèi)型都可以被顯式地聲明(或隱式地轉(zhuǎn)換)為可選類(lèi)型。如果你在聲明或定義可選變量或?qū)傩缘臅r(shí)候沒(méi)有提供初始值,它的值則會(huì)自動(dòng)賦為默認(rèn)值 nil。

如果一個(gè)可選類(lèi)型的實(shí)例包含一個(gè)值,那么你就可以使用后綴運(yùn)算符 ! 來(lái)獲取該值,正如下面描述的:

optionalInteger = 42
optionalInteger! // 42

使用 ! 運(yùn)算符解包值為 nil 的可選值會(huì)導(dǎo)致運(yùn)行錯(cuò)誤。

你也可以使用可選鏈?zhǔn)秸{(diào)用和可選綁定來(lái)選擇性地在可選表達(dá)式上執(zhí)行操作。如果值為 nil,不會(huì)執(zhí)行任何操作,因此也就沒(méi)有運(yùn)行錯(cuò)誤產(chǎn)生。

更多細(xì)節(jié)以及更多如何使用可選類(lèi)型的例子,請(qǐng)參閱 可選類(lèi)型。

可選類(lèi)型語(yǔ)法

可選類(lèi)型類(lèi)型 ?

隱式解析可選類(lèi)型

當(dāng)可以被訪問(wèn)時(shí),Swift 語(yǔ)言定義后綴 ! 作為標(biāo)準(zhǔn)庫(kù)中命名類(lèi)型 Optional<Wrapped> 的語(yǔ)法糖,來(lái)實(shí)現(xiàn)自動(dòng)解包的功能。換句話(huà)說(shuō),下面兩個(gè)聲明等價(jià):

var implicitlyUnwrappedString: String!
var explicitlyUnwrappedString: Optional<String>

注意類(lèi)型與 ! 之間沒(méi)有空格。

由于隱式解包修改了包涵其類(lèi)型的聲明語(yǔ)義,嵌套在元組類(lèi)型或泛型的可選類(lèi)型(比如字典元素類(lèi)型或數(shù)組元素類(lèi)型),不能被標(biāo)記為隱式解包。例如:

let tupleOfImplicitlyUnwrappedElements: (Int!, Int!)  // 錯(cuò)誤
let implicitlyUnwrappedTuple: (Int, Int)!             // 正確

let arrayOfImplicitlyUnwrappedElements: [Int!]        // 錯(cuò)誤
let implicitlyUnwrappedArray: [Int]!                  // 正確

由于隱式解析可選類(lèi)型和可選類(lèi)型有同樣的表達(dá)式 Optional<Wrapped>,你可以在使用可選類(lèi)型的地方使用隱式解析可選類(lèi)型。比如,你可以將隱式解析可選類(lèi)型的值賦給變量、常量和可選屬性,反之亦然。

正如可選類(lèi)型一樣,你在聲明隱式解析可選類(lèi)型的變量或?qū)傩缘臅r(shí)候也不用指定初始值,因?yàn)樗心J(rèn)值 nil。

可以使用可選鏈?zhǔn)秸{(diào)用來(lái)在隱式解析可選表達(dá)式上選擇性地執(zhí)行操作。如果值為 nil,就不會(huì)執(zhí)行任何操作,因此也不會(huì)產(chǎn)生運(yùn)行錯(cuò)誤。

關(guān)于隱式解析可選類(lèi)型的更多細(xì)節(jié),請(qǐng)參閱 隱式解析可選類(lèi)型。

隱式解析可選類(lèi)型語(yǔ)法

隱式解析可選類(lèi)型類(lèi)型 !

協(xié)議合成類(lèi)型

協(xié)議合成類(lèi)型是一種符合協(xié)議列表中每個(gè)指定協(xié)議的類(lèi)型。協(xié)議合成類(lèi)型可能會(huì)用在類(lèi)型注解和泛型參數(shù)中。

協(xié)議合成類(lèi)型的形式如下:

Protocol 1 & Procotol 2

協(xié)議合成類(lèi)型允許你指定一個(gè)值,其類(lèi)型符合多個(gè)協(xié)議的要求且不需要定義一個(gè)新的命名型協(xié)議來(lái)繼承它想要符合的各個(gè)協(xié)議。比如,協(xié)議合成類(lèi)型 Protocol A & Protocol B & Protocol C 等效于一個(gè)從 Protocol AProtocol B,Protocol C 繼承而來(lái)的新協(xié)議 Protocol D,很顯然這樣做有效率的多,甚至不需引入一個(gè)新名字。

協(xié)議合成列表中的每項(xiàng)必須是協(xié)議名或協(xié)議合成類(lèi)型的類(lèi)型別名。

協(xié)議合成類(lèi)型語(yǔ)法

協(xié)議合成類(lèi)型協(xié)議標(biāo)識(shí)符 & 協(xié)議合成延續(xù) 協(xié)議合成延續(xù)協(xié)議標(biāo)識(shí)符 | 協(xié)議合成類(lèi)型 協(xié)議標(biāo)識(shí)符類(lèi)型標(biāo)識(shí)符

元類(lèi)型

元類(lèi)型是指類(lèi)型的類(lèi)型,包括類(lèi)類(lèi)型、結(jié)構(gòu)體類(lèi)型、枚舉類(lèi)型和協(xié)議類(lèi)型。

類(lèi)、結(jié)構(gòu)體或枚舉類(lèi)型的元類(lèi)型是相應(yīng)的類(lèi)型名緊跟 .Type。協(xié)議類(lèi)型的元類(lèi)型——并不是運(yùn)行時(shí)符合該協(xié)議的具體類(lèi)型——而是該協(xié)議名字緊跟 .Protocol。比如,類(lèi) SomeClass 的元類(lèi)型就是 SomeClass.Type,協(xié)議 SomeProtocol 的元類(lèi)型就是 SomeProtocal.Protocol。

你可以使用后綴 self 表達(dá)式來(lái)獲取類(lèi)型。比如,SomeClass.self 返回 SomeClass 本身,而不是 SomeClass 的一個(gè)實(shí)例。同樣,SomeProtocol.self 返回 SomeProtocol 本身,而不是運(yùn)行時(shí)符合 SomeProtocol 的某個(gè)類(lèi)型的實(shí)例。還可以對(duì)類(lèi)型的實(shí)例使用 type(of:) 表達(dá)式來(lái)獲取該實(shí)例在運(yùn)行階段的類(lèi)型,如下所示:

class SomeBaseClass {
    class func printClassName() {
        println("SomeBaseClass")
    }
}
class SomeSubClass: SomeBaseClass {
    override class func printClassName() {
        println("SomeSubClass")
    }
}
let someInstance: SomeBaseClass = SomeSubClass()
// someInstance 在編譯期是 SomeBaseClass 類(lèi)型,
// 但是在運(yùn)行期則是 SomeSubClass 類(lèi)型
type(of: someInstance).printClassName()
// 打印 “SomeSubClass”

更多信息可以查看 Swift 標(biāo)準(zhǔn)庫(kù)里的 type(of:)。

可以使用初始化表達(dá)式從某個(gè)類(lèi)型的元類(lèi)型構(gòu)造出一個(gè)該類(lèi)型的實(shí)例。對(duì)于類(lèi)實(shí)例,被調(diào)用的構(gòu)造器必須使用 required 關(guān)鍵字標(biāo)記,或者整個(gè)類(lèi)使用 final 關(guān)鍵字標(biāo)記。

class AnotherSubClass: SomeBaseClass {
    let string: String
    required init(string: String) {
        self.string = string
    }
    override class func printClassName() {
        print("AnotherSubClass")
    }
}
let metatype: AnotherSubClass.Type = AnotherSubClass.self
let anotherInstance = metatype.init(string: "some string")

元類(lèi)型語(yǔ)法

元類(lèi)型類(lèi)型 . Type | 類(lèi)型 . Protocol

類(lèi)型繼承子句

類(lèi)型繼承子句被用來(lái)指定一個(gè)命名型類(lèi)型繼承自哪個(gè)類(lèi)、采納哪些協(xié)議。類(lèi)型繼承子句也用來(lái)指定一個(gè)類(lèi)類(lèi)型專(zhuān)屬協(xié)議。類(lèi)型繼承子句開(kāi)始于冒號(hào) :,其后是所需要的類(lèi)、類(lèi)型標(biāo)識(shí)符列表或兩者都有。

類(lèi)可以繼承單個(gè)超類(lèi),采納任意數(shù)量的協(xié)議。當(dāng)定義一個(gè)類(lèi)時(shí),超類(lèi)的名字必須出現(xiàn)在類(lèi)型標(biāo)識(shí)符列表首位,然后跟上該類(lèi)需要采納的任意數(shù)量的協(xié)議。如果一個(gè)類(lèi)不是從其它類(lèi)繼承而來(lái),那么列表可以以協(xié)議開(kāi)頭。關(guān)于類(lèi)繼承更多的討論和例子,請(qǐng)參閱 繼承

其它命名型類(lèi)型可能只繼承或采納一系列協(xié)議。協(xié)議類(lèi)型可以繼承自任意數(shù)量的其他協(xié)議。當(dāng)一個(gè)協(xié)議類(lèi)型繼承自其它協(xié)議時(shí),其它協(xié)議中定義的要求會(huì)被整合在一起,然后從當(dāng)前協(xié)議繼承的任意類(lèi)型必須符合所有這些條件。正如在 協(xié)議聲明 中所討論的那樣,可以把 class 關(guān)鍵字放到協(xié)議類(lèi)型的類(lèi)型繼承子句的首位,這樣就可以聲明一個(gè)類(lèi)類(lèi)型專(zhuān)屬協(xié)議。

枚舉定義中的類(lèi)型繼承子句可以是一系列協(xié)議,或是枚舉的原始值類(lèi)型的命名型類(lèi)型。在枚舉定義中使用類(lèi)型繼承子句來(lái)指定原始值類(lèi)型的例子,請(qǐng)參閱 原始值。

類(lèi)型繼承子句語(yǔ)法

類(lèi)型繼承子句: 類(lèi)型繼承列表 類(lèi)型繼承列表類(lèi)型標(biāo)識(shí)符 | 類(lèi)型標(biāo)識(shí)符 , 類(lèi)型繼承列表

類(lèi)型推斷

Swift 廣泛使用類(lèi)型推斷,從而允許你省略代碼中很多變量和表達(dá)式的類(lèi)型或部分類(lèi)型。比如,對(duì)于 var x: Int = 0,你可以完全省略類(lèi)型而簡(jiǎn)寫(xiě)成 var x = 0,編譯器會(huì)正確推斷出 x 的類(lèi)型 Int。類(lèi)似的,當(dāng)完整的類(lèi)型可以從上下文推斷出來(lái)時(shí),你也可以省略類(lèi)型的一部分。比如,如果你寫(xiě)了 let dict: Dictionary = ["A" : 1],編譯器能推斷出 dict 的類(lèi)型是 Dictionary<String, Int>

在上面的兩個(gè)例子中,類(lèi)型信息從表達(dá)式樹(shù)的葉子節(jié)點(diǎn)傳向根節(jié)點(diǎn)。也就是說(shuō),var x: Int = 0x 的類(lèi)型首先根據(jù) 0 的類(lèi)型進(jìn)行推斷,然后將該類(lèi)型信息傳遞到根節(jié)點(diǎn)(變量 x)。

在 Swift 中,類(lèi)型信息也可以反方向流動(dòng)——從根節(jié)點(diǎn)傳向葉子節(jié)點(diǎn)。在下面的例子中,常量 eFloat 上的顯式類(lèi)型注解(: Float)將導(dǎo)致數(shù)字字面量 2.71828 的類(lèi)型是 Float 而非 Double

let e = 2.71828 // e 的類(lèi)型會(huì)被推斷為 Double
let eFloat: Float = 2.71828 // eFloat 的類(lèi)型為 Float

Swift 中的類(lèi)型推斷在單獨(dú)的表達(dá)式或語(yǔ)句上進(jìn)行。這意味著所有用于類(lèi)型推斷的信息必須可以從表達(dá)式或其某個(gè)子表達(dá)式的類(lèi)型檢查中獲取到。