本文系閱讀閱讀原章節後總結概括得出。由於需要我進行一定的概括提煉,如有不當之處歡迎讀者斧正。如果你對內容有任何疑問,歡迎共同交流討論。
隱式可選型別也是可選型別,它們會在你使用到的時候自動解封。那為什麼還要用隱式可選型別呢,主要有兩個原因:
- 與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?
型別。
- 只會短暫的為
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"
複製程式碼