Swift4.0學(xué)習(xí)第一篇

1.常量和變量

常量和變量把一個(gè)名字和一個(gè)指定類型的值關(guān)聯(lián)起來(lái)。常量的值一旦設(shè)定就不能改變,而變量的值可以隨意更改。

1.1聲明常量和變量

常量和變量必須在使用前聲明,用 let 來(lái)聲明常量,用 var 來(lái)聲明變量。

let maximumNumberOfLoginAttempts = 10//允許的最大嘗試登錄次數(shù)
var currentLoginAttempt = 0//當(dāng)前嘗試登錄次數(shù)

這兩行代碼可以被理解為:
聲明一個(gè)名字是 maximumNumberOfLoginAttempts 的新常量,并給它一個(gè)值 10 。然后,聲明一個(gè)名字是 currentLoginAttempt 的變量并將它的值初始化為 0 。在這個(gè)例子中,允許的最大嘗試登錄次數(shù)被聲明為一個(gè)常量,因?yàn)檫@個(gè)值不會(huì)改變。當(dāng)前嘗試登錄次數(shù)被聲明為一個(gè)變量,因?yàn)槊看螄L試登錄失敗的時(shí)候都需要增加這個(gè)值。

你可以在一行中聲明多個(gè)常量或者多個(gè)變量,用逗號(hào)隔開(kāi):

var x = 1.0, y = 2.0, z = 3.0
var x = 12, y = 22, z = 32

1.2類型的標(biāo)注

當(dāng)你聲明常量或者變量的時(shí)候可以加上類型標(biāo)注(type annotation),說(shuō)明常量或者變量中要存儲(chǔ)的值的類
型。如果要添加類型標(biāo)注,需要在常量或者變量名后面加上一個(gè)冒號(hào)和空格,然后加上類型名稱。

這個(gè)例子給 welcomeMessage 變量添加了類型標(biāo)注,表示這個(gè)變量可以存儲(chǔ) String 類型的值:

var welcomeMessage: String

聲明中的冒號(hào)代表著“是…類型”,所以這行代碼可以被理解為:
“聲明一個(gè)類型為 String ,名字為 welcomeMessage 的變量?!?br> “類型為 String ”的意思是“可以存儲(chǔ)任意 String 類型的值?!?br> welcomeMessage 變量現(xiàn)在可以被設(shè)置成任意字符串:

welcomeMessage = "Hello"

你可以在一行中定義多個(gè)同樣類型的變量,用逗號(hào)分割,并在最后一個(gè)變量名之后添加類型標(biāo)注:

var red, green, blue: Double

注意:
一般來(lái)說(shuō)你很少需要寫(xiě)類型標(biāo)注。如果你在聲明常量或者變量的時(shí)候賦了一個(gè)初始值,Swift可以推斷出這個(gè)常
量或者變量的類型。在上面的例子中,沒(méi)有給 welcomeMessage 賦初始
值,所以變量 welcomeMessage 的類型是通過(guò)一個(gè)類型標(biāo)注指定的,而不是通過(guò)初始值推斷的。

1.3常量和變量的命名
你可以用任何你喜歡的字符作為常量和變量名,包括 Unicode 字符:

let π = 3.14159
let 你好 = "你好世界"
let ?? = "dogcow"

常量與變量名不能包含數(shù)學(xué)符號(hào),箭頭,保留的(或者非法的)Unicode 碼位,連線與制表符。也不能以數(shù)字開(kāi)
頭,但是可以在常量與變量名的其他地方包含數(shù)字。

一旦你將常量或者變量聲明為確定的類型,你就不能使用相同的名字再次進(jìn)行聲明,或者改變其存儲(chǔ)的值的類
型。同時(shí),你也不能將常量與變量進(jìn)行互轉(zhuǎn)。

注意:
如果你需要使用與Swift保留關(guān)鍵字相同的名稱作為常量或者變量名,你可以使用反引號(hào)(`)將關(guān)鍵字包圍的方
式將其作為名字使用。無(wú)論如何,你應(yīng)當(dāng)避免使用關(guān)鍵字作為常量或變量名。

你可以更改現(xiàn)有的變量值為其他同類型的值,在下面的例子中, friendlyWelcome 的值從 “Hello!” 改為了 “Bonj our!” :

var friendlyWelcome = "Hello!"
friendlyWelcome = "Bonjour!"
// friendlyWelcome 現(xiàn)在是 “Bonjour!” 

與變量不同,常量的值一旦被確定就不能更改了。嘗試這樣做會(huì)導(dǎo)致編譯時(shí)報(bào)錯(cuò):

let languageName = "Swift"
languageName = "Swift++"
// 這會(huì)報(bào)編譯時(shí)錯(cuò)誤 - languageName 不可改變

1.4輸出常量和變量
你可以用 print(_:separator:terminator:) 函數(shù)來(lái)輸出當(dāng)前常量或變量的值:

print(friendlyWelcome)
// 輸出 “Bonjour!” 

print(_:separator:terminator:) 是一個(gè)用來(lái)輸出一個(gè)或多個(gè)值到適當(dāng)輸出區(qū)的全局函數(shù)

注意:Swift 用字符串插值(string interpolation)的方式把常量名或者變量名當(dāng)做占位符加入到長(zhǎng)字符串中,Swift 會(huì)
用當(dāng)前常量或變量的值替換這些占位符。將常量或變量名放入圓括號(hào)中,并在開(kāi)括號(hào)前使用反斜杠將其轉(zhuǎn)義:

print("The current value of friendlyWelcome is \(friendlyWelcome)")
// 輸出 "The current value of friendlyWelcome is Bonjour!

2.注釋

2.1 單行注釋

Swift 中的注釋與C 語(yǔ)言的注釋非常相似。單行注釋以雙正斜杠( // )作為起始標(biāo)記:

// 這是一個(gè)注釋

2.2 行多行注釋,

其起始標(biāo)記為單個(gè)正斜杠后跟隨一個(gè)星號(hào)( /* ),終止標(biāo)記為一個(gè)星號(hào)后跟隨單個(gè)正斜杠( */ ):

/* 這是一個(gè),
多行注釋 */

2.3 Swift 的多行注釋可以嵌套在其它的多行注釋之中

/* 這是第一個(gè)多行注釋的開(kāi)頭
/* 這是第二個(gè)被嵌套的多行注釋 */
這是第一個(gè)多行注釋的結(jié)尾 */

3. 分號(hào)

Swift 并不強(qiáng)制要求你在每條語(yǔ)句的結(jié)尾處使用分號(hào)( ; ),當(dāng)然,你也可以按照你自己的習(xí)慣添加分號(hào)。有一種情況下必須要用分號(hào),即你打算在同一行內(nèi)寫(xiě)多條獨(dú)立的語(yǔ)句:

let cat = "?"; print(cat);var title :String;
// 輸出 "?"

4. 整數(shù)

整數(shù)就是沒(méi)有小數(shù)部分的數(shù)字,比如 42 和 -23 。整數(shù)可以是 有符號(hào) (正、負(fù)、零)或者 無(wú)符號(hào) (正、零)。
Swift 提供了8,16,32和64位的有符號(hào)和無(wú)符號(hào)整數(shù)類型。這些整數(shù)類型和 C 語(yǔ)言的命名方式很像,比如8位
無(wú)符號(hào)整數(shù)類型是 UInt8 ,32位有符號(hào)整數(shù)類型是 Int32 。就像 Swift 的其他類型一樣,整數(shù)類型采用大寫(xiě)命名
法。

4.1整數(shù)范圍

你可以訪問(wèn)不同整數(shù)類型的 min 和 max 屬性來(lái)獲取對(duì)應(yīng)類型的最小值和最大值:

let minValue = UInt8.min // minValue 為 0,是 UInt8 類型
let maxValue = UInt8.max // maxValue 為 255,是 UInt8 類型

min 和 max 所傳回值的類型,正是其所對(duì)的整數(shù)類型(如上例UInt8, 所傳回的類型是UInt8),可用在表達(dá)式中相同類型值旁。

4.2 Int

一般來(lái)說(shuō),你不需要專門(mén)指定整數(shù)的長(zhǎng)度。Swift 提供了一個(gè)特殊的整數(shù)類型 Int ,長(zhǎng)度與當(dāng)前平臺(tái)的原生字長(zhǎng)相
同:
? 在32位平臺(tái)上, Int 和 Int32 長(zhǎng)度相同。
? 在64位平臺(tái)上, Int 和 Int64 長(zhǎng)度相同。
除非你需要特定長(zhǎng)度的整數(shù),一般來(lái)說(shuō)使用 Int 就夠了。這可以提高代碼一致性和可復(fù)用性。即使是在32位平臺(tái)
上, Int 可以存儲(chǔ)的整數(shù)范圍也可以達(dá)到 -2,147,483,648 ~ 2,147,483,647 ,大多數(shù)時(shí)候這已經(jīng)足夠大了。

4.3UInt

Swift 也提供了一個(gè)特殊的無(wú)符號(hào)類型 UInt ,長(zhǎng)度與當(dāng)前平臺(tái)的原生字長(zhǎng)相同:
? 在32位平臺(tái)上, UInt 和 UInt32 長(zhǎng)度相同。
? 在64位平臺(tái)上, UInt 和 UInt64 長(zhǎng)度相同。
注意:
盡量不要使用 UInt ,除非你真的需要存儲(chǔ)一個(gè)和當(dāng)前平臺(tái)原生字長(zhǎng)相同的無(wú)符號(hào)整數(shù)。除了這種情況,最好使用 Int ,即使你要存儲(chǔ)的值已知是非負(fù)的。統(tǒng)一使用 Int 可以提高代碼的可復(fù)用性,避免不同類型數(shù)字之間的轉(zhuǎn)換,并且匹配數(shù)字的類型推斷。

5.浮點(diǎn)數(shù)

浮點(diǎn)數(shù)是有小數(shù)部分的數(shù)字,比如 3.14159 , 0.1 和 -273.15 。
浮點(diǎn)類型比整數(shù)類型表示的范圍更大,可以存儲(chǔ)比 Int 類型更大或者更小的數(shù)字。Swift 提供了兩種有符號(hào)浮點(diǎn)數(shù)
類型:
? Double 表示64位浮點(diǎn)數(shù)。當(dāng)你需要存儲(chǔ)很大或者很高精度的浮點(diǎn)數(shù)時(shí)請(qǐng)使用此類型。
? Float 表示32位浮點(diǎn)數(shù)。精度要求不高的話可以使用此類型。
注意:

Double 精確度很高,至少有15位數(shù)字,而 Float 最少只有6位數(shù)字。選擇哪個(gè)類型取決于你的代碼需要處理的
值的范圍。

6.類型安全和類型推斷

Swift 是一個(gè)類型安全(type safe)的語(yǔ)言。類型安全的語(yǔ)言可以讓你清楚地知道代碼要處理的值的類型。如果你的代碼需要一個(gè) String ,你絕對(duì)不可能不小心傳進(jìn)去一個(gè) Int 。由于 Swift 是類型安全的,所以它會(huì)在編譯你的代碼時(shí)進(jìn)行類型檢查(type checks),并把不匹配的類型標(biāo)記
為錯(cuò)誤。這可以讓你在開(kāi)發(fā)的時(shí)候盡早發(fā)現(xiàn)并修復(fù)錯(cuò)誤。

當(dāng)你要處理不同類型的值時(shí),類型檢查可以幫你避免錯(cuò)誤。然而,這并不是說(shuō)你每次聲明常量和變量的時(shí)候都需要顯式指定類型。如果你沒(méi)有顯式指定類型,Swift 會(huì)使用 類型推斷 (type inference)來(lái)選擇合適的類型。有了類型推斷,編譯器可以在編譯代碼的時(shí)候自動(dòng)推斷出表達(dá)式的類型。原理很簡(jiǎn)單,只要檢查你賦的值即可。

因?yàn)橛蓄愋屯茢?,?C 或者 Objective-C 比起來(lái) Swift 很少需要聲明類型。常量和變量雖然需要明確類型,但是大部分工作并不需要你自己來(lái)完成。當(dāng)你聲明常量或者變量并賦初值的時(shí)候類型推斷非常有用。當(dāng)你在聲明常量或者變量的時(shí)候賦給它們一個(gè)字面量(literal value 或 literal)即可觸發(fā)類型推斷。(字面量就是會(huì)直接出現(xiàn)在你代碼中的值,比如 42 和 3.14159 。)
例如,如果你給一個(gè)新常量賦值 42 并且沒(méi)有標(biāo)明類型,Swift 可以推斷出常量類型是 Int ,因?yàn)槟憬o它賦的初始
值看起來(lái)像一個(gè)整數(shù):

let meaningOfLife = 42
// meaningOfLife 會(huì)被推測(cè)為 Int 類型

同理,如果你沒(méi)有給浮點(diǎn)字面量標(biāo)明類型,Swift 會(huì)推斷你想要的是 Double :

let pi = 3.14159
// pi 會(huì)被推測(cè)為 Double 類型

當(dāng)推斷浮點(diǎn)數(shù)的類型時(shí),Swift 總是會(huì)選擇 Double 而不是 Float 。
如果表達(dá)式中同時(shí)出現(xiàn)了整數(shù)和浮點(diǎn)數(shù),會(huì)被推斷為 Double 類型:

let anotherPi = 3 + 0.14159
// anotherPi 會(huì)被推測(cè)為 Double 類型

原始值 3 沒(méi)有顯式聲明類型,而表達(dá)式中出現(xiàn)了一個(gè)浮點(diǎn)字面量,所以表達(dá)式會(huì)被推斷為 Double 類型。

7.數(shù)值型字面量

整數(shù)字面量可以被寫(xiě)作:

? 一個(gè)十進(jìn)制數(shù),沒(méi)有前綴
? 一個(gè)二進(jìn)制數(shù),前綴是 0b
? 一個(gè)八進(jìn)制數(shù),前綴是 0o
? 一個(gè)十六進(jìn)制數(shù),前綴是 0x

下面的所有整數(shù)字面量的十進(jìn)制值都是 17 :

let decimalInteger = 17
let binaryInteger = 0b10001 // 二進(jìn)制的17
let octalInteger = 0o21 // 八進(jìn)制的17
let hexadecimalInteger = 0x11 // 十六進(jìn)制的17

浮點(diǎn)字面量可以是十進(jìn)制(沒(méi)有前綴)或者是十六進(jìn)制(前綴是 0x )。小數(shù)點(diǎn)兩邊必須有至少一個(gè)十進(jìn)制數(shù)
字(或者是十六進(jìn)制的數(shù)字)。浮點(diǎn)字面量還有一個(gè)可選的指數(shù)(exponent,在十進(jìn)制浮點(diǎn)數(shù)中通過(guò)大寫(xiě)或者小
寫(xiě)的 e 來(lái)指定,在十六進(jìn)制浮點(diǎn)數(shù)中通過(guò)大寫(xiě)或者小寫(xiě)的 p 來(lái)指定。
如果一個(gè)十進(jìn)制數(shù)的指數(shù)為 exp ,那這個(gè)數(shù)相當(dāng)于基數(shù)和10^exp的乘積: * 1.25e2 表示 1.25 × 10^2,等于
125.0 。 * 1.25e-2 表示 1.25 × 10^-2,等于 0.0125 。
如果一個(gè)十六進(jìn)制數(shù)的指數(shù)為 exp ,那這個(gè)數(shù)相當(dāng)于基數(shù)和2^exp的乘積: * 0xFp2 表示 15 × 2^2,等于 6
0.0 。 * 0xFp-2 表示 15 × 2^-2,等于 3.75 。
下面的這些浮點(diǎn)字面量都等于十進(jìn)制的 12.1875 :

let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0

數(shù)值類字面量可以包括額外的格式來(lái)增強(qiáng)可讀性。整數(shù)和浮點(diǎn)數(shù)都可以添加額外的零并且包含下劃線,并不會(huì)影
響字面量:

let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1

8.數(shù)值型類型轉(zhuǎn)換

通常來(lái)講,即使代碼中的整數(shù)常量和變量已知非負(fù),也請(qǐng)使用 Int 類型??偸鞘褂媚J(rèn)的整數(shù)類型可以保證你的
整數(shù)常量和變量可以直接被復(fù)用并且可以匹配整數(shù)類字面量的類型推斷。
只有在必要的時(shí)候才使用其他整數(shù)類型,比如要處理外部的長(zhǎng)度明確的數(shù)據(jù)或者為了優(yōu)化性能、內(nèi)存占用等
等。使用顯式指定長(zhǎng)度的類型可以及時(shí)發(fā)現(xiàn)值溢出并且可以暗示正在處理特殊數(shù)據(jù)。

8.2整數(shù)轉(zhuǎn)換

不同整數(shù)類型的變量和常量可以存儲(chǔ)不同范圍的數(shù)字。 Int8 類型的常量或者變量可以存儲(chǔ)的數(shù)字范圍是 -12
8 ~ 127 ,而 UInt8 類型的常量或者變量能存儲(chǔ)的數(shù)字范圍是 0 ~ 255 。如果數(shù)字超出了常量或者變量可存儲(chǔ)的
范圍,編譯的時(shí)候會(huì)報(bào)錯(cuò):

let cannotBeNegative: UInt8 = -1
// UInt8 類型不能存儲(chǔ)負(fù)數(shù),所以會(huì)報(bào)錯(cuò)
let tooBig: Int8 = Int8.max + 1
// Int8 類型不能存儲(chǔ)超過(guò)最大值的數(shù),所以會(huì)報(bào)錯(cuò)

由于每種整數(shù)類型都可以存儲(chǔ)不同范圍的值,所以你必須根據(jù)不同情況選擇性使用數(shù)值型類型轉(zhuǎn)換。這種選擇性
使用的方式,可以預(yù)防隱式轉(zhuǎn)換的錯(cuò)誤并讓你的代碼中的類型轉(zhuǎn)換意圖變得清晰。
要將一種數(shù)字類型轉(zhuǎn)換成另一種,你要用當(dāng)前值來(lái)初始化一個(gè)期望類型的新數(shù)字,這個(gè)數(shù)字的類型就是你的目標(biāo)
類型。在下面的例子中,常量 twoThousand 是 UInt16 類型,然而常量 one 是 UInt8 類型。它們不能直接相
加,因?yàn)樗鼈冾愋筒煌K砸{(diào)用 UInt16(one) 來(lái)創(chuàng)建一個(gè)新的 UInt16 數(shù)字并用 one 的值來(lái)初始化,然后使
用這個(gè)新數(shù)字來(lái)計(jì)算:
let twoThousand: UInt16 = 2_000
let one: UInt8 = 1
let twoThousandAndOne = twoThousand + UInt16(one)
現(xiàn)在兩個(gè)數(shù)字的類型都是 UInt16 ,可以進(jìn)行相加。目標(biāo)常量 twoThousandAndOne 的類型被推斷為 UInt16 ,因?yàn)樗莾蓚€(gè) UInt16 值的和。

SomeType(ofInitialValue) 是調(diào)用 Swift 構(gòu)造器并傳入一個(gè)初始值的默認(rèn)方法。在語(yǔ)言內(nèi)部, UInt16 有一個(gè)構(gòu)
造器,可以接受一個(gè) UInt8 類型的值,所以這個(gè)構(gòu)造器可以用現(xiàn)有的 UInt8 來(lái)創(chuàng)建一個(gè)新的 UInt16 。注意,你
并不能傳入任意類型的值,只能傳入 UInt16 內(nèi)部有對(duì)應(yīng)構(gòu)造器的值。不過(guò)你可以擴(kuò)展現(xiàn)有的類型來(lái)讓它可以接收
其他類型的值(包括自定義類型).

8.3整數(shù)和浮點(diǎn)數(shù)轉(zhuǎn)換

整數(shù)和浮點(diǎn)數(shù)的轉(zhuǎn)換必須顯式指定類型:

let three = 3
let pointOneFourOneFiveNine = 0.14159
let pi = Double(three) + pointOneFourOneFiveNine
// pi 等于 3.14159,所以被推測(cè)為 Double 類型

這個(gè)例子中,常量 three 的值被用來(lái)創(chuàng)建一個(gè) Double 類型的值,所以加號(hào)兩邊的數(shù)類型須相同。如果不進(jìn)行轉(zhuǎn)
換,兩者無(wú)法相加。
浮點(diǎn)數(shù)到整數(shù)的反向轉(zhuǎn)換同樣行,整數(shù)類型可以用 Double 或者 Float 類型來(lái)初始化:

let integerPi = Int(pi)
// integerPi 等于 3,所以被推測(cè)為 Int 類型

當(dāng)用這種方式來(lái)初始化一個(gè)新的整數(shù)值時(shí),浮點(diǎn)值會(huì)被截?cái)?。也就是說(shuō) 4.75 會(huì)變成 4 , -3.9 會(huì)變成 -3 。
注意:
結(jié)合數(shù)字類常量和變量不同于結(jié)合數(shù)字類字面量。字面量 3 可以直接和字面量 0.14159 相加,因?yàn)閿?shù)字字面量
本身沒(méi)有明確的類型。它們的類型只在編譯器需要求值的時(shí)候被推測(cè)。

9.類型別名

類型別名(type aliases)就是給現(xiàn)有類型定義另一個(gè)名字。你可以使用 typealias 關(guān)鍵字來(lái)定義類型別名。
當(dāng)你想要給現(xiàn)有類型起一個(gè)更有意義的名字時(shí),類型別名非常有用。假設(shè)你正在處理特定長(zhǎng)度的外部資源的數(shù)據(jù):
typealias AudioSample = UInt16
定義了一個(gè)類型別名之后,你可以在任何使用原始名的地方使用別名:

var maxAmplitudeFound = AudioSample.min
// maxAmplitudeFound 現(xiàn)在是 0

本例中, AudioSample 被定義為 UInt16 的一個(gè)別名。因?yàn)樗莿e名, AudioSample.min 實(shí)際上是 UInt16.mi
n ,所以會(huì)給 maxAmplitudeFound 賦一個(gè)初值 0 。

10 布爾值(Bool)

Swift 有一個(gè)基本的布爾(Boolean)類型,叫做 Bool 。布爾值指邏輯上的值,因?yàn)樗鼈冎荒苁钦婊蛘呒?。Swift 有兩個(gè)布爾常量, true 和 false :

let orangesAreOrange = true
let turnipsAreDelicious = false

orangesAreOrange 和 turnipsAreDelicious 的類型會(huì)被推斷為 Bool ,因?yàn)樗鼈兊某踔凳遣紶栕置媪?。就像之前提到?Int 和 Double 一樣,如果你創(chuàng)建變量的時(shí)候給它們賦值 true 或者 false ,那你不需要將常量或者變量聲明為 Bool 類型。初始化常量或者變量的時(shí)候如果所賦的值類型已知,就可以觸發(fā)類型推斷,這讓 Swift 代碼更加簡(jiǎn)潔并且可讀性更高。當(dāng)你編寫(xiě)條件語(yǔ)句比如 if 語(yǔ)句的時(shí)候,布爾值非常有用:

if turnipsAreDelicious {
print("Mmm, tasty turnips!")
} else {
print("Eww, turnips are horrible.")
}
// 輸出 "Eww, turnips are horrible."

條件語(yǔ)句,例如 if 如果你在需要使用 Bool 類型的地方使用了非布爾值,Swift 的類型安全機(jī)制會(huì)報(bào)錯(cuò)。下面的例子會(huì)報(bào)告一個(gè)編譯
時(shí)錯(cuò)誤:

let i = 1
if i {
// 這個(gè)例子不會(huì)通過(guò)編譯,會(huì)報(bào)錯(cuò)
}

然而,下面的例子是合法的:

let i = 1
if i == 1 {
// 這個(gè)例子會(huì)編譯成功
}

i == 1 的比較結(jié)果是 Bool 類型,所以第二個(gè)例子可以通過(guò)類型檢查。類似 i == 1 這樣的比較.和 Swift 中的其他類型安全的例子一樣,這個(gè)方法可以避免錯(cuò)誤并保證這塊代碼的意圖總是清晰的。

11.元組

元組(tuples)把多個(gè)值組合成一個(gè)復(fù)合值。元組內(nèi)的值可以是任意類型,并不要求是相同類型。
下面這個(gè)例子中, (404, “Not Found”) 是一個(gè)描述 HTTP 狀態(tài)碼(HTTP status code)的元組。HTTP 狀態(tài)
碼是當(dāng)你請(qǐng)求網(wǎng)頁(yè)的時(shí)候 web 服務(wù)器返回的一個(gè)特殊值。如果你請(qǐng)求的網(wǎng)頁(yè)不存在就會(huì)返回一個(gè) 404 Not Foun
d 狀態(tài)碼。

let http404Error = (404, "Not Found")
// http404Error 的類型是 (Int, String),值是 (404, "Not Found")

(404, “Not Found”) 元組把一個(gè) Int 值和一個(gè) String 值組合起來(lái)表示 HTTP 狀態(tài)碼的兩個(gè)部分:一個(gè)數(shù)字和一
個(gè)人類可讀的描述。這個(gè)元組可以被描述為“一個(gè)類型為 (Int, String) 的元組”。
你可以把任意順序的類型組合成一個(gè)元組,這個(gè)元組可以包含所有類型。只要你想,你可以創(chuàng)建一個(gè)類型為 (Int, I
nt, Int) 或者 (String, Bool) 或者其他任何你想要的組合的元組。
你可以將一個(gè)元組的內(nèi)容分解(decompose)成單獨(dú)的常量和變量,然后你就可以正常使用它們了:

let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)")
// 輸出 "The status code is 404"
print("The status message is \(statusMessage)")
// 輸出 "The status message is Not Found"

如果你只需要一部分元組值,分解的時(shí)候可以把要忽略的部分用下劃線( _ )標(biāo)記:

let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)")
// 輸出 "The status code is 404"

此外,你還可以通過(guò)下標(biāo)來(lái)訪問(wèn)元組中的單個(gè)元素,下標(biāo)從零開(kāi)始:

print("The status code is \(http404Error.0)")
// 輸出 "The status code is 404"
print("The status message is \(http404Error.1)")
// 輸出 "The status message is Not Found"

你可以在定義元組的時(shí)候給單個(gè)元素命名:
let http200Status = (statusCode: 200, description: “OK”)
給元組中的元素命名后,你可以通過(guò)名字來(lái)獲取這些元素的值:

print("The status code is \(http200Status.statusCode)")
// 輸出 "The status code is 200"
print("The status message is \(http200Status.description)")
// 輸出 "The status message is OK"

作為函數(shù)返回值時(shí),元組非常有用。一個(gè)用來(lái)獲取網(wǎng)頁(yè)的函數(shù)可能會(huì)返回一個(gè) (Int, String) 元組來(lái)描述是否獲取
成功。和只能返回一個(gè)類型的值比較起來(lái),一個(gè)包含兩個(gè)不同類型值的元組可以讓函數(shù)的返回信息更有用。請(qǐng)參
考函數(shù)參數(shù)與返回值 (頁(yè) 0)。
注意:
元組在臨時(shí)組織值的時(shí)候很有用,但是并不適合創(chuàng)建復(fù)雜的數(shù)據(jù)結(jié)構(gòu)。如果你的數(shù)據(jù)結(jié)構(gòu)并不是臨時(shí)使用,請(qǐng)使
用類或者結(jié)構(gòu)體而不是元組。請(qǐng)參考類和結(jié)構(gòu)體。

10.可選類型

10.1nil

你可以給可選變量賦值為 nil 來(lái)表示它沒(méi)有值:

var serverResponseCode: Int? = 404
// serverResponseCode 包含一個(gè)可選的 Int 值 404
serverResponseCode = nil
// serverResponseCode 現(xiàn)在不包含值

注意:
nil 不能用于非可選的常量和變量。如果你的代碼中有常量或者變量需要處理值缺失的情況,請(qǐng)把它們聲明成對(duì)
應(yīng)的可選類型。
如果你聲明一個(gè)可選常量或者變量但是沒(méi)有賦值,它們會(huì)自動(dòng)被設(shè)置為 nil :

var surveyAnswer: String? 
// surveyAnswer 被自動(dòng)設(shè)置為 nil

11.錯(cuò)誤處理

你可以使用錯(cuò)誤處理(error handling)來(lái)應(yīng)對(duì)程序執(zhí)行中可能會(huì)遇到的錯(cuò)誤條件。
相對(duì)于可選中運(yùn)用值的存在與缺失來(lái)表達(dá)函數(shù)的成功與失敗,錯(cuò)誤處理可以推斷失敗的原因,并傳播至程序的其
他部分。
當(dāng)一個(gè)函數(shù)遇到錯(cuò)誤條件,它能報(bào)錯(cuò)。調(diào)用函數(shù)的地方能拋出錯(cuò)誤消息并合理處理。

func canThrowAnErrow() throws {
// 這個(gè)函數(shù)有可能拋出錯(cuò)誤
}

一個(gè)函數(shù)可以通過(guò)在聲明中添加 throws 關(guān)鍵詞來(lái)拋出錯(cuò)誤消息。當(dāng)你的函數(shù)能拋出錯(cuò)誤消息時(shí), 你應(yīng)該在表達(dá)式
中前置 try 關(guān)鍵詞。

do {
try canThrowAnErrow()
// 沒(méi)有錯(cuò)誤消息拋出
} catch {
// 有一個(gè)錯(cuò)誤消息拋出
}

一個(gè) do 語(yǔ)句創(chuàng)建了一個(gè)新的包含作用域,使得錯(cuò)誤能被傳播到一個(gè)或多個(gè) catch 從句。
這里有一個(gè)錯(cuò)誤處理如何用來(lái)應(yīng)對(duì)不同錯(cuò)誤條件的例子。

func makeASandwich() throws {
// ...
}
do {
try makeASandwich()
eatASandwich()
} catch Error.OutOfCleanDishes {
washDishes()
} catch Error.MissingIngredients(let ingredients) {
buyGroceries(ingredients)
}

在此例中, makeASandwich() (做一個(gè)三明治)函數(shù)會(huì)拋出一個(gè)錯(cuò)誤消息如果沒(méi)有干凈的盤(pán)子或者某個(gè)原料缺
失。因?yàn)?makeASandwich() 拋出錯(cuò)誤,函數(shù)調(diào)用被包裹在 try 表達(dá)式中。將函數(shù)包裹在一個(gè) do 語(yǔ)句中,任何被
拋出的錯(cuò)誤會(huì)被傳播到提供的 catch 從句中。

如果沒(méi)有錯(cuò)誤被拋出, eatASandwich() 函數(shù)會(huì)被調(diào)用。如果一個(gè)匹配 Error.OutOfCleanDishes 的錯(cuò)誤被拋出, washDishes 函數(shù)會(huì)被調(diào)用。如果一個(gè)匹配 Error.MissingIngredients 的錯(cuò)誤被拋出,buyGroceries(_:) 函數(shù)會(huì)隨著被 catch 所捕捉到的關(guān)聯(lián)值 [String] 被調(diào)用。拋出,捕捉,以及傳播錯(cuò)誤會(huì)在錯(cuò)誤處理。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 關(guān)于 Swift 重要這個(gè)文檔所包含的準(zhǔn)備信息, 是關(guān)于開(kāi)發(fā)的 API 和技術(shù)的。這個(gè)信息可能會(huì)改變, 根據(jù)這個(gè)文...
    無(wú)灃閱讀 4,622評(píng)論 1 27
  • Swift 是一門(mén)開(kāi)發(fā) iOS, macOS, watchOS 和 tvOS 應(yīng)用的新語(yǔ)言。然而,如果你有 C 或...
    XLsn0w閱讀 987評(píng)論 2 1
  • [The Swift Programming Language 中文版] Swift 是一門(mén)開(kāi)發(fā) iOS, OS ...
    風(fēng)林山火閱讀 390評(píng)論 0 0
  • “滴滴滴滴....”照例被鬧鐘吵醒。打開(kāi)手機(jī),看到屏幕上已經(jīng)6點(diǎn)半吧。先看看今天的天氣,看看今天的運(yùn)勢(shì)如何,今天不...
    夢(mèng)回一夏閱讀 534評(píng)論 0 0
  • 看到本周的話題,起初我覺(jué)得很輕松,自認(rèn)為是幸福感很強(qiáng)的媽媽,面對(duì)這樣的話題自然有很多話要講??墒?,眼看著時(shí)間一天天...
    貪睡的點(diǎn)點(diǎn)閱讀 344評(píng)論 0 0

友情鏈接更多精彩內(nèi)容