元組
元組(tuples)把多個值組合成一個復合值。元組內的值可以是任意類型,并不要求是相同類型。
//創建一個元組
let http = (404,"not Found",true,"prf")
print(http)//輸出結果是:(404, "not Found", true, "prf")
//元組的的內容還可以被分解
let (a,b,c,d) = http
print(a)
print(b)
print(c)
print(d)
//如果在分解的時候,只需要用到其中一部分元組的值,則不需要的用到的部分用`_`來代替
let (x,y,_,_) = http
print(x,y)
/*還可以通過下標來訪問元組中的指定位置的元素,
原理有點像OC中的數組,例如我要訪問元組http中第二位元素*/
print(http.1)
//在定義元組的時候,還可以為它其的元素命名
let dog = (name:"泰迪",age:2)
print(dog.name,dog.age)//然后還可以通過元組的元素名字來訪問它,這又有點像訪問一個對象的屬性一樣
元組的使用場景
作為函數返回值時,元組非常有用。一個用來獲取網頁的函數可能會返回一個 (Int, String)
元組來描述是否獲取成功。和只能返回一個類型的值比較起來,一個包含兩個不同類型值的元組可以讓函數的返回信息更有用。請參考函數參數與返回值。
注意:
元組在臨時組織值的時候很有用,但是并不適合創建復雜的數據結構。如果你的數據結構并不是臨時使用,請使用類或者結構體而不是元組。請參考類和結構體。
可選類型
在Swift中,可選值是用來處理值可能缺失的情況,在C和OC中都沒有這種概念,不過它又和OC中的函數返回值概念有點像,例如一個函數要不返回一個值,要不返回一個nil
,然而,這只對對象起作用——對于結構體,基本的 C 類型或者枚舉類型不起作用。
//定義一個常量字符串
let possibleNumber = "123"
/*通過Int構造器將其轉化成Int類型,并不是每一個字符串都可以轉化成Int類型
字符串 "123" 可以被轉換成數字 123 ,但是字符串 "hello, world" 不行。*/
let convertedNumber = Int(possibleNumber)
// convertedNumber 被推測為類型 "Int?", 或者類型 "optional Int"
以上代碼,因為構造器返回的結果可能失敗,所以它返回一個可選類型(optional)Int 或者Int?,而不是一個 Int。一個可選的 Int 被寫作 Int? 而不是 Int。問號暗示包含的值是可選類型,也就是說可能包含 Int 值也可能不包含值。(不能包含其他任何值比如 Bool 值或者 String 值。只能是 Int 或者什么都沒有。)
//1).原始的可選值定義
// Optional是一個枚舉,里面有兩個值,none:沒有值,some 某一類值
let x:Optional = 10
//輸出結果:Optional(10) ,提示程序員這是一個可選值
print(x)
//2).簡單定義
//Int? 用來表示 y 是一個可選的Int類型,可能是沒有,可能是一個Int類型
let y:Int? = 20
//輸出結果:Optional(20)
print(y)
print(x + y)//這種寫法會報錯
print(x! + y!)//正確寫法
//1>不同類型之間不能直接運算,如果沒有值不能參與運算所以不能直接( x + y)
//2>`!`強行解包-從可選值中,強行獲取非空值(非nil,如果最后只能得到nil運行會崩潰);
//可以給可選值變量賦值為nil
var name : String? = "prf"
name = nil //這個時候,name里就不包含值了
/*注意:nil不能用于非可選的常量和變量。
如果你的代碼中有常量或者變量需要處理值缺失的情況,請把它們聲明成對應的可選類型。*/
常見錯誤
//常見錯誤1
let y:Int?
print(y)//這是編譯會報錯,提示常量y,沒有初始化
//常見錯誤2
let x: Optional = 10
let y: Int? = 20
print(x! +y!)
//運行會崩潰
//原因:Unexpectedly found nil while unwrapping an Optional value
//在強行解包可選值時,發現值為nil
if 語句以及強制解析
//可以使用 if 語句和 nil 比較來判斷一個可選值是否包含值
let x:Optional = 10
if x != nil {
print("x is contains some integer value")
}
let y:Int? = nil
if y == nil {
print("y is nil")
}
可選綁定(Optional binding)
可選綁定可以用來判斷可選類型是否包含值,如果包含就把值賦給一個臨時常量或者變量。
let possibleNumber = "123"
if let actualNumber = Int(possibleNumber) {
print("\'\(possibleNumber)\' has an integer value of \(actualNumber)")
} else {
print("\'\(possibleNumber)\' could not be converted to an integer")
}
// 輸出 "'123' has an integer value of 123"
隱式解析可選類型
可選類型暗示了常量或者變量可以“沒有值”。可選可以通過 if 語句來判斷是否有值,如果有值的話可以通過可選綁定來解析值。
有時候(并不總是)在程序架構中,第一次被賦值之后,可以確定一個可選類型總會有值。在這種情況下,每次都要判斷和解析可選值是非常低效的,因為可以確定它總會有值。
這種類型的可選狀態被定義為隱式解析可選類型(implicitly unwrapped optionals)。把想要用作可選的類型的后面的問號(String?)改成感嘆號(String!)來聲明一個隱式解析可選類型。
當可選類型被第一次賦值之后就可以確定之后一直有值的時候,隱式解析可選類型非常有用。隱式解析可選類型主要被用在 Swift 中類的構造過程中,請參考無主引用以及隱式解析可選屬性。
一個隱式解析可選類型其實就是一個普通的可選類型,但是可以被當做非可選類型來使用,并不需要每次都使用解析來獲取可選值。下面的例子展示了可選類型 String 和隱式解析可選類型 String 之間的區別:
let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // 需要感嘆號來獲取值
let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // 不需要感嘆號
//是在不能理解蘋果為什么會推出一個這樣的東西有點多余
//從書寫上僅僅感覺是為了后面不用不斷地寫!而已