從第一天接觸Swift開始,接觸最多的話題就是圍繞Optional的,那么為什么要有Optional類型呢?下面談一下我自己的理解:
首先舉一個例子,UIImage有一個構造方法,通過圖片的名字生成一個UIImage對象:UIImage(named:"imageName")。當指定名字的圖片存在時,肯定會返回一個UIImage的實例,但如果圖片不存在,那么就不能返回UIImage實例了,那么這個時候返回什么呢?在Objective-C中,會返回nil來表示失敗的情況。
但是Swift是一種對類型有嚴格要求的類型,一個函數或方法不能返回兩種類型的值,必須是一個明確的類型,但是一個方法有成功和失敗兩種情況又是不可避免的,那么怎么處理這種情況呢?
我們可以這樣考慮一下,如果我們聲明一種類型,它的成員有兩個,一個用于存儲成功的情況,一個用來存儲失敗的情況,然后將有可能失敗的方法的返回值類型設置為我們指定的這種類型,問題好像就解決了。對于方法的調用者,在拿到結果之后,可以判斷哪個成員有值,就可以做相應的處理了。
由于成功和失敗的情況不可能同時出現,并且Swift中的enum可以支持關聯值,因此用enum來表示這個類型應該就可以了。由于不同函數返回的真正的數據類型是不一樣的,因此需要該enum類型必須支持范型才可以。
在Swift中,表示這種類型的數據結構就是Optional,它就是一個enum,且支持范型。它有兩種情況,.Some關聯真正的值,.None表示失敗的情況。Optional 的定義部分代碼如下:
public enum Optional<Wrapped>: NilLiteralConvertible {
case Some(Wrapped)
case None
// 幾個初始化方法
public init(_ some: Wrapped) {
self = .Some(some)
}
public init(nilLieral: ()) {
self = .None
}
public init() {
self = .None
}
}
為了方便處理Optional的結果,Swift提供了if-let 和 guard兩種方式來幫助判斷結果是兩種情況的那一種。
并且nil在Swift中就是Optional.None,二者是等價的,者與Objective-C中的nil是不一樣的。
以上只是Optional的基本概念和最基本的用法,Optional在復雜場景下理解起來還是比較麻煩的,比如Optioanl嵌套的情況等。
最后總結一下Optional的幾條規則:
1、Optional支持多層嵌套
2、由于Optional的 init(_ some: Wrapped)的構造函數,可以將一個N級的Optional值賦值給一個N+1級的Optional的變量。
3、由于Optiona init(nilLiteral: ())構造函數的作用,可以將nil賦值給任意層級的Optional變量。
4、由于Optional嵌套比較復雜,容易出錯,因此盡量避免使用Optional嵌套。
5、嵌套Optional會出現if let 操作失效的問題。