第四章——隱式可選型別

bestswifter發表於2017-12-27

本文系閱讀閱讀原章節後總結概括得出。由於需要我進行一定的概括提煉,如有不當之處歡迎讀者斧正。如果你對內容有任何疑問,歡迎共同交流討論。

隱式可選型別也是可選型別,它們會在你使用到的時候自動解封。那為什麼還要用隱式可選型別呢,主要有兩個原因:

  1. 與OC混編

我們有可能在swift中呼叫OC的方法,返回一個指標。在寫OC時,指標為空是一種很常見的情況,這樣一來在Swift中我們可能得到一個引用或者是nil,所以返回值必須是可選型別的。由於很少有方法真的返回空指標,所以把返回值全部定義為可選型別有些得不償失,而把它定義為隱式可選型別其實是一種權衡。

舉個例子:

//OC定義了一個返回值為NSString *的方法
- (NSString *)giveName;
複製程式碼
//swift中呼叫這個方法
var name = p.giveName()
複製程式碼

這時候name的型別為String!,因為OC一側沒有明確表示返回的指標是否可能為空,swift認為它理論上可以是空指標,但實際上不太可能發生。如果改一下OC的的方法定義:

- (nullable NSString *)giveName;
複製程式碼

這樣name的型別為String?。因為OC一側已經很明確的表示了,這個返回的指標有可能為空。所以swift很自然地把它定義為String?型別。

  1. 只會短暫的為nil,但是在隨後一段確定的時間內,一定不可能為nil

儘管隱式可選型別儘可能的隱藏了它可選型別的特性,讓你在使用時感覺它和非可選型別非常相似,但它依然與非可選型別有一些微小的區別,比如你不能把它作為被標記成inout 的引數使用:

func increment(inout x: Int) {
++x
}

var i = 1
increment(&i) // i = 2

var j: Int! = 1
increment(&j) // 編譯錯誤
// Cannot invoke 'increment' with an argument list of type 'inout Int!'
複製程式碼

隱式可選型別作為一種可選型別,它依然具有可選型別的特性。比如你可以使用可選鏈、空合運算子,if let隱式繫結以及map方法等:

var s: String! = "Hello"
s?.isEmpty  // 使用可選鏈,返回結果為可選型別的false
if let s = s { print(s) } // 隱式繫結,結果為列印"Hello"
s = nil
s ?? "Goodbye"  // 空合運算子,返回結果為"Goodbye"
複製程式碼

相關文章