初學(xué)Swift的時候,被! 和 ? 整懵了,為什么這些類型后面要加個問號,亂七八糟的,不過只要寫錯了,xcode就會給出提示,修改后就沒問題了。一直都沒有深入研究。這幾天研究了一下這個可選類型,發(fā)現(xiàn)這個東西真的好。
在我看來,可選類型是為了安全而出現(xiàn)的。它避免了空指針異常這種情況。比如:
?` ? var str : String`
聲明一個String類型的str,沒有給它賦初值,這句話是沒有問題的。但是當(dāng)我們使用它的時候,比如:
str.uppercaseString
就會有空指針異常,而且這個問題在OC或者JAVA里,只有在運行時才會崩潰,而在Swift里引用了可選類型,就可以在編譯時就給出警告,這就是我理解的可選類型的意義。
可選類型改寫上面的代碼:
var str : String?
str?.uppercaseString
第一行代碼,在類型后面加一個?,說明這是一個可選類型,可選類型可以說是該類型的超集,包括String類型和一個nil值。
第二行代碼,在調(diào)用方法前加一個?,該句的作用是如果str為nil,那么不執(zhí)行后面的語句,如果不為nil,才執(zhí)行uppercaseString,這被稱為可選類型的鏈?zhǔn)讲僮鳎@有效避免了空指針異常,保證運行時安全。
還有一個概念是解包(unwrap)
可選類型是不可以直接使用的,比如:
var str : String? = "abc"
let str2 = str
會報錯,因為str是可選類型,你必須拆包后才能使用它的值,加一個 感嘆號 !,這就是解包!
let str2 = str!
告訴編譯器,這個值肯定是存在而不是nil的。有人說,誒,這不就不安全了么,我怎么知道它是不是nil啊,沒錯。所以這種寫法不推薦,除非你確定這個值肯定不為nil。
那么,這種寫法應(yīng)該更安全些:
var str : String? = "abc"
if let str2 = str{
print(str2)
}
這種if let 語句,判斷str是否為 nil,如果不為nil,執(zhí)行括號內(nèi)代碼,否則執(zhí)行else
不過有人會說了,這樣好麻煩,寫代碼好累。確實,為了安全是要犧牲一些東西的,原來為了省錢,總是把電動車停在收費停車場外面,直到電瓶被偷才追悔莫及,所以為了安全,請交一塊錢停車費吧。
況且,蘋果還提供了更加方便的代碼來使用:
var str2 = str == nil ? "error" : str!
三目運算符,如果為nil,則給str2賦“error”
還有更簡單的
var str2 = str ?? "error"
效果是相同的,推薦使用第二個。
除此之外,還有一種隱式可選型:
var str : String!
它在使用時不用解包,直接使用
str.uppercaseString
可見這種用法并不安全,所以它的使用率不是很高,通常在類的聲明里使用,比如,在類的在init()中不想對某個變量初始化,就加一個!,具體怎么使用再慢慢深究吧。