轉(zhuǎn)載自SegmentFault
一般我們?cè)谝幌聝煞N情況下會(huì)遇到!和?的使用
1.聲明變量時(shí)
var number :Int?
var str : String!
2.在對(duì)變量操作時(shí)
number?.hashValue
str!.hashValue
由于這兩種情況的意義不同,所以分開進(jìn)行解釋:
1.聲明變量時(shí)
在聲明一個(gè)變量時(shí)如果不手動(dòng)初始化,Swift不會(huì)自動(dòng)初始化該變量為一個(gè)默認(rèn)值的。
var a : String
var b = a //error:因?yàn)闆]有初始化a,a沒有值
但是對(duì)于Optional的變量則不同,Optional的變量在聲明時(shí)如果不初始化,Swift會(huì)自動(dòng)將該變量初始化為nil。聲明變量時(shí)在類型后添加?或者!就是告訴編譯器這個(gè)一個(gè)Optional的變量,如果沒有初始化,你就將其初始化為nil
var a : String? //a 為nil
var b : String! //b 為nil
var a_test = a //a_test為nil
var b_test = b //b_test為nil
但是這兩者之間還是有一些區(qū)別的,介紹后面之后再講。Optional事實(shí)上是一個(gè)枚舉類型,從下圖可以看出,Optional包含None和Some兩種類型,而nil就是Optional.None,非nil就是Optional.some。如果Optional變量在聲明時(shí)不初始化,Swift會(huì)調(diào)用init()來初始化變量為nil,而用非nil的值初始化變量時(shí),會(huì)通過Some(T)把該原始值包裝,所以在之后使用的時(shí)候我們需要通過解包取出原始值才能使用。
2.對(duì)變量進(jìn)行操作時(shí)
var arrayCount = dataList?.count
這時(shí)問號(hào)的意思類似于isResponseToSelector,即如果變量是nil,則不能響應(yīng)后面的方法,所以會(huì)直接返回nil。如果變量非nil,就會(huì)拆Some(T)的包,取出原始值執(zhí)行后面的操作。
var arrayCount = dataList!.count
這里的嘆號(hào)和之前的問號(hào)則不同,這里表示我確定dataList一定是非nil的,所以直接拆包取出原始值進(jìn)行處理。因此此處如果不小心讓dataList為nil,程序就會(huì)crash掉。
回到上面聲明時(shí) ?和 !區(qū)別的問題上去
聲明變量時(shí)的 ?只是單純的告訴Swift這是Optional的,如果沒有初始化就默認(rèn)為nil,而通過!聲明,則之后對(duì)該變量操作的時(shí)候都會(huì)隱式的在操作前添加一個(gè)!
總結(jié)
- 問號(hào)?
a.聲明時(shí)添加?,告訴編譯器這個(gè)是Optional的,如果聲明時(shí)沒有手動(dòng)初始化,就自動(dòng)初始化為nil
b.在對(duì)變量值操作前添加?,判斷如果變量時(shí)nil,則不響應(yīng)后面的方法。 - 嘆號(hào)!
a.聲明時(shí)添加!,告訴編譯器這個(gè)是Optional的,并且之后對(duì)該變量操作的時(shí)候,都隱式的在操作前添加!
b.在對(duì)變量操作前添加!,表示默認(rèn)為非nil,直接解包進(jìn)行處理