可選類型定義
Swift 標準庫中定義后綴 ??為可選類型 Optional<Wrapped> 的語法糖,這里語法糖可以簡單理解為一種便捷的書寫語法。也就是說,下面兩個聲明是等價的:
var name: Optional<String>
var name: String?
上述兩種情況,變量 name 被聲明為可選字符串類型。
我們可以在xcode編譯器中,按住 command 鍵 同時點擊 OPtional,可以跟進去查看可選類型的具體實現:
public enum Optional: ExpressibleByNilLiteral {
? ? ? ? ? ? /// The absence of a value.
? ? ? ? ? ? /// In code, the absence of a value is typically written using the `nil`
? ? ? ? ? ? /// literal rather than the explicit `.none` enumeration case.
? ? ? ? ? ? case none
? ? ? ? ? ? /// The presence of a value, stored as `Wrapped`.
? ? ? ? ? ? case some(Wrapped)
? ? ? ? ? ? /// Creates an instance that stores the given value.
? ? ? ? ? ? public init(_ some: Wrapped)
? ? ? ? ? ? 其他部分省略。。。。
}
我們看到,可選類型 Optional<Wrapped> 是一個枚舉,有兩個成員:none 和 some(Wrapped),表示可能沒有值或者可能有值。
var name: String?
print(name)
//打印:nil
name = "haha"
print(name)
//打印:Optional("haha")
上述例子,name聲明為可選類型,沒有初始化的時候,自動置為nil。當你聲明一個可選變量或常量但沒有賦初值,它們都會被自動置為nil。
注意:Swift 的 nil 和 Objective-C 中的 nil 并不一樣。在 Objective-C 中,nil 是一個指向不存在對象的指針。在 Swift 中,nil 不是指針——它是一個確定的值,用來表示值缺失。任何類型的可選狀態都可以被設置為 nil,不只是對象類型,但非可選的類型值不能置為nil。
if 語句以及強制解析
可以使用 if 語句 和 nil 比較來判斷一個可選值是否有值:
if name != nil {
print(name!)
}
//打印:"haha"
當確定可選值有值的時候,可以在變量名后跟 !符號來強制解析該可選值,注意,不能用 !強制解析不包含值的可選值,否則導致運行出錯。
可選綁定
使用可選綁定來判斷一個可選值是否包含值,若包含值則賦給一個臨時變量或常量。如下可選綁定用在 if ?語句中:
if let nick = name {
print(nick)
}
//打印:"haha"
這段代碼可以理解為:可選值 name 包含一個值“haha”,則創建一個臨時的新常量 nick 并把可選值 name 的值賦給它。
?還可以包含多個可選綁定或多個布爾條件在一個 if 語句中,只要使用逗號分開就行。只要有任意一個可選綁定的值為nil,或者任意一個布爾條件為false,則整個if條件判斷為false。
隱式解析可選類型
有時候在程序中,第一次賦值后,可以確定一個可選類型總是有值,這樣,在以后的調用中總是判斷和解析可選值是效率低下的,這種類型的可選狀態為被定義為隱式解析可選類型。把想要用作可選類型的 ?改為 !來聲明一個隱式解析可選類型。隱式解析可選類型依然是一個可選類型,可選類型的特性它同樣適用,只是注意,當隱式解析可選項值為 nil 的時候解析取值,會運行出錯。如果一個變量之后可能變成nil的話請不要使用隱式解析可選類型。如果你需要在變量的生命周期中判斷是否是nil的話,請使用普通可選類型。
var hehe: String! = "hehe"
var s1: String = hehe? //s1類型是 String
var s2 = hehe? ? ? ? //s2類型是由 hehe 推斷出為 可選類型 String?,所以下面打印格式不同
print(hehe,s1,s2)
//打印:hehe hehe Optional("hehe")