生活随笔
收集整理的這篇文章主要介紹了
初探swift语言的学习笔记二(可选类型?和隐式可选类型!)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
作者:fengsh998
原文地址:http://blog.csdn.net/fengsh998/article/details/28904115
轉(zhuǎn)載請(qǐng)注明出處
如果覺得文章對(duì)你有所幫助,請(qǐng)通過(guò)留言或關(guān)注微信公眾帳號(hào) fengsh998 來(lái)支持我,謝謝!
可選類型、隱式可選類型
在swift中,可選類型其根源是一個(gè)枚舉型,里面有None和Some兩種類型。其實(shí)所謂的nil就是Optional.None, 非nil就是Optional.Some, 然后會(huì)通過(guò)Some(T)包裝(wrap)原始值,這也是為什么在使用Optional的時(shí)候要拆包(從enum里取出來(lái)原始值)的原因, 也是PlayGround會(huì)把Optional值顯示為類似{Some "hello world"}的原因,這里是enum Optional的定義:
[cpp] ?view plaincopy
enum ?Optional<T>?:?LogicValue,?Reflectable?{?? ????case ?None?? ????case ?Some(T)?? ????init()?? ????init(_?some:?T)?? ?? ?????? ????func?getLogicValue()?->?Bool?? ?? ?????? ????func?map<U>(f:?(T)?->?U)?->?U??? ????func?getMirror()?->?Mirror?? }??
語(yǔ)法使用“?” 操作符及"!" 號(hào)操作符
如:“var optionalString: String? =? "Hello" optionalString == nil ? var optionalName: String? = "John Appleseed" var greeting = "Hello!" if let name = optionalName { ? ? greeting = "Hello, \(name)" }” 大家把optionalName改為nil時(shí)看一下會(huì)有什么結(jié)果?按照理解,應(yīng)該是? = 后的為可選值,即當(dāng)我們的的變量為nil時(shí),這里如果有?=操作,則會(huì)使用?=后的值作為默認(rèn)值,而不會(huì)為nil. 這個(gè)等有環(huán)境時(shí),驗(yàn)證一下。
經(jīng)驗(yàn)證:
分別執(zhí)行:
[cpp] ?view plaincopy
var?optional?:String??=? "ok?good" ; ?? println(optional)??
輸出為:
ok good
與
[cpp] ?view plaincopy
var?optional?:String? ?? println(optional)??
輸出為:
nil
來(lái)看下!號(hào),官方釋為隱式解包:主要用在一個(gè)變量/常量在定義瞬間完成之后值一定會(huì)存在的情況。這主要用在類的初始化過(guò)程中。
官風(fēng)例子:
[cpp] ?view plaincopy
let?possibleString:?String??=? "An?optional?string." ?? println(possibleString!)??? ?? ?? let?assumedString:?String!?=?"An?implicitly?unwrapped?optional?string." ?? println(assumedString)???
實(shí)說(shuō)話,你照這個(gè)例子運(yùn)行,還真看不出什么,得不出什么結(jié)論。因此我自己Z磨著,試著理解一個(gè)英文翻譯。再自己操刀練習(xí)。得出下面的一些結(jié)論。
[cpp] ?view plaincopy
var?optionVariables:String?? ?? ?? let?value?=?optionVariables?.hashValue?? ? ? ? ? ? ? ?? ?? ?? ?? ?? ?? if ?let?hv?=?optionVariables?? {?? ?????? }?? ?? ?? let?hv?=?optionVariables!.hashValue?? ?? ?? ?? if ?optionVariables?{?? ????let?hashv?=?optionVariables!.hashValue?? }?? ??
凡在變量或常量后加上?的都是一個(gè)可選變量/可選常量 凡在變量或常量后加上!的都是隱式可選變量/常量,有點(diǎn)難理解,首先該變量或常量滿足可選類型,其主要是可被當(dāng)生一般的變量/常量來(lái)使用,而不需要每次都驗(yàn)證是否有值。
注:如果一個(gè)隱式解包的可選類型不包含一個(gè)實(shí)際值,那么對(duì)它的訪問(wèn)會(huì)拋出一個(gè)運(yùn)行時(shí)錯(cuò)誤。在變量/常量名后面加!的情況也是一樣的。
[cpp] ?view plaincopy
var?possibleString:?String??=? "An?optional?string." ?? ?? println(possibleString)???
分析:首先 possibleString 因后面帶上了?說(shuō)明這是一個(gè)可選的,同時(shí)前面加上var為變量,所以這是一個(gè)可選類型的變量。其可選值為 "An optional string." 再來(lái)看執(zhí)行println后,可以看出輸出為 An optional string. 這點(diǎn)很明顯。再來(lái)看一下把println這句改一下改為 (即在可選變量后面加上一個(gè)!號(hào)。)
[cpp] ?view plaincopy
<span?style= "font-size:18px;" >println(possibleString!)? ??
這里結(jié)果與沒有加!號(hào)時(shí)是完全一樣的,輸出為An optional string.?
好,現(xiàn)在重點(diǎn)來(lái)了,這是很關(guān)鍵的一個(gè)測(cè)試。把possibleString = nil 這句注釋放開讓其動(dòng)行,再分別來(lái)看一下println帶!和不帶!的情況:
情況一:不帶!號(hào)時(shí),輸出為nil .
[cpp] ?view plaincopy
<span?style= "font-size:18px;" >????????var?possibleString:?String??=? "An?optional?string." ?? ????????possibleString?=?nil?? ????????println(possibleString)?</span>??
情況二:再來(lái)看一下帶!號(hào)
[cpp] ?view plaincopy
<span?style= "font-size:18px;" >????????var?possibleString:?String??=? "An?optional?string." ?? ????????possibleString?=?nil?? ????????println(possibleString!)???
這時(shí)運(yùn)行到這句println就會(huì)crash了。會(huì)報(bào)
fatal error: Can't unwrap Optional.None
錯(cuò)誤。?
在情況一時(shí),為什么不會(huì)報(bào)錯(cuò),是因?yàn)檫@是一個(gè)可選變量當(dāng)變量為nil時(shí),自動(dòng)驗(yàn)證是否有可選的值,有則使用可選值,在情況二,加上!訪問(wèn)符來(lái)訪問(wèn)possibleString 變量,但由于possibleString設(shè)為了nil (等價(jià)于var possibleString: String?) 其并沒有包含一個(gè)實(shí)際值,所以拋異常.同樣對(duì)于下面使用!號(hào)來(lái)聲明的也一樣道:
[cpp] ?view plaincopy
<span?style= "font-size:18px;" >????????var?assumedString:?String!?=? "An?implicitly?unwrapped?optional?string." ?? ????????assumedString?=?nil?? ????????println(assumedString!)</span>??
同樣會(huì)報(bào):fatal error: Can't unwrap Optional.None
如果你定義了一個(gè)可選類型并且沒有給予初始值的時(shí)候,會(huì)默認(rèn)設(shè)置為nil var surveyAnswer: String? // 初自動(dòng)設(shè)置為nil 注: Swift 的nil不同于Object-C中的nil. Object-C中,nil是一個(gè)指針指向不存在的對(duì)象。Swift中,nil不是指針而是一個(gè)特定類型的空值。任何類型的可選變量都可以被設(shè)為nil,不光是指針。
在swift中作何變量/常量的聲明都必須帶有初始值,否則就要聲明為可選型。
即var btn:UIButton 這樣是編譯報(bào)錯(cuò)的。因些必須改為帶初始化的如:
var ?btn2 : UIButton?=? UIButton()
或者使用? 和! 來(lái)約束。
因此常常聲明可選或隱式可選變量如:
var btn :UIButton? ? ? ?// 默認(rèn)btn = nil
var edt :UITextField! ?// 默認(rèn)edt = nil
至于什么時(shí)候使用?什么情況下使用!號(hào)來(lái)約束變量,我還沒有悟出真真原理。
因此借助于自己的幾次驗(yàn)證來(lái)幫助大家理解。
[cpp] ?view plaincopy
<span?style= "font-size:18px;" >????????var?btn??:UIButton??????? ?? ????????var?btn2?:UIButton?=?UIButton()?????? ????????var?btn3?:UIButton!??????? ?????????? ?????????? ????????btn!.tintColor?=?UIColor.blackColor()?? ????????btn!.imageEdgeInsets?=?UIEdgeInsets(top:1,left:2,bottom:3,right:4)?? ????????btn!.frame?=?CGRectMake(0,0,50,40)?? ?????????? ?????????? ????????btn2.tintColor?=?UIColor.blackColor()?? ????????btn2.imageEdgeInsets?=?UIEdgeInsets(top:1,left:2,bottom:3,right:4)?? ????????btn2.frame?=?CGRectMake(0,0,50,40)?? ?????????? ?????????? ????????btn3.tintColor?=?UIColor.blackColor()?? ????????btn3.imageEdgeInsets?=?UIEdgeInsets(top:1,left:2,bottom:3,right:4)?? ????????btn3.frame?=?CGRectMake(0,0,50,40)</span>??
因此為了運(yùn)行期不crash可以改為如下:
[cpp] ?view plaincopy
<span?style= "font-size:18px;" >????????var?btn??:UIButton??????? ?? ????????var?btn2?:UIButton?=?UIButton()?????? ????????var?btn3?:UIButton!??????? ?????????? ?????????? ????????if ?var?tmpbtn?=?btn?? ????????{?? ????????????btn!.tintColor?=?UIColor.blackColor()?? ????????????btn!.imageEdgeInsets?=?UIEdgeInsets(top:1,left:2,bottom:3,right:4)?? ????????????btn!.frame?=?CGRectMake(0,0,50,40)?? ????????}?? ?????????? ?????????? ????????btn2.tintColor?=?UIColor.blackColor()?? ????????btn2.imageEdgeInsets?=?UIEdgeInsets(top:1,left:2,bottom:3,right:4)?? ????????btn2.frame?=?CGRectMake(0,0,50,40)?? ?????????? ?????????? ????????if ?var?tmpbtn?=?btn?? ????????{?? ????????????btn3.tintColor?=?UIColor.blackColor()?? ????????????btn3.imageEdgeInsets?=?UIEdgeInsets(top:1,left:2,bottom:3,right:4)?? ????????????btn3.frame?=?CGRectMake(0,0,50,40)?? ????????}</span>??
或者
[cpp] ?view plaincopy
<span?style= "font-size:18px;" >????????var?btn??:UIButton??????? ?? ????????var?btn2?:UIButton?=?UIButton()?????? ????????var?btn3?:UIButton!??????? ?????????? ?????????? ????????if ?btn?? ????????{?? ????????????btn!.tintColor?=?UIColor.blackColor()?? ????????????btn!.imageEdgeInsets?=?UIEdgeInsets(top:1,left:2,bottom:3,right:4)?? ????????????btn!.frame?=?CGRectMake(0,0,50,40)?? ????????}?? ?????????? ?????????? ????????btn2.tintColor?=?UIColor.blackColor()?? ????????btn2.imageEdgeInsets?=?UIEdgeInsets(top:1,left:2,bottom:3,right:4)?? ????????btn2.frame?=?CGRectMake(0,0,50,40)?? ?????????? ?????????? ????????if ?btn3?? ????????{?? ????????????btn3.tintColor?=?UIColor.blackColor()?? ????????????btn3.imageEdgeInsets?=?UIEdgeInsets(top:1,left:2,bottom:3,right:4)?? ????????????btn3.frame?=?CGRectMake(0,0,50,40)?? ????????}</span>??
注:如果一個(gè)可選類型存在沒有值的可能的話,不應(yīng)該使用解包(隱式)可選類型。這種情況下,一定要使用正常的可選類型。
這句話我個(gè)人是這樣理解的,如var view:UIView。當(dāng)我的整個(gè)應(yīng)用中或整個(gè)類中不可能存在view = nil的情況時(shí)可以設(shè)置為var view:UIView! 否則就可聲明為var view:UIView?
與50位技術(shù)專家面對(duì)面 20年技術(shù)見證,附贈(zèng)技術(shù)全景圖
總結(jié)
以上是生活随笔 為你收集整理的初探swift语言的学习笔记二(可选类型?和隐式可选类型!) 的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。