Swift語言中問號(hào) ? 和 感嘆號(hào) ! 的作用

Swift語言使用var定義變量春寿,但和別的語言不同笔喉,Swift里不會(huì)自動(dòng)給變量賦初始值,也就是說變量不會(huì)有默認(rèn)值鬼雀,所以要求使用變量之前必須要對其初始化顷窒。如果在使用變量之前不進(jìn)行初始化就會(huì)報(bào)錯(cuò):

var stringValue : String 
//error: variable 'stringValue' used before being initialized
//let hashValue = stringValue.hashValue
//                            ^
let hashValue = stringValue.hashValue

上面了解到的是普通值,接下來Optional值要上場了。經(jīng)喵神提醒鞋吉,Optional其實(shí)是個(gè)enum鸦做,里面有None和Some兩種類型。其實(shí)所謂的nil就是Optional.None, 非nil就是Optional.Some, 然后會(huì)通過Some(T)包裝(wrap)原始值谓着,這也是為什么在使用Optional的時(shí)候要拆包(從enum里取出來原始值)的原因, 也是PlayGround會(huì)把Optional值顯示為類似{Some "hello world"}的原因泼诱,這里是enum Optional的定義:

enum Optional<T> : LogicValue, Reflectable {
    case None
    case Some(T)
    init()
    init(_ some: T)

    /// Allow use in a Boolean context.
    func getLogicValue() -> Bool

    /// Haskell's fmap, which was mis-named
    func map<U>(f: (T) -> U) -> U?
    func getMirror() -> Mirror
}

聲明為Optional只需要在類型后面緊跟一個(gè)?即可。如:

var strValue: String?   //?相當(dāng)于下面這種寫法的語法糖
var strValue: Optional<Int>  

一旦聲明為Optional的赊锚,如果不顯式的賦值就會(huì)有個(gè)默認(rèn)值nil治筒。判斷一個(gè)Optional的值是否有值,可以用if來判斷:

if strValue {
    //do sth with strValue
}

然后怎么使用Optional值呢舷蒲?文檔中也有提到說耸袜,在使用Optional值的時(shí)候需要在具體的操作,比如調(diào)用方法牲平、屬性堤框、下標(biāo)索引等前面需要加上一個(gè)?,經(jīng)喵神指正纵柿,”O(jiān)ptional Chaining的問號(hào)的意思是詢問是否響應(yīng)后面這個(gè)方法蜈抓,和原來的isResponseToSelector有些類似”,如果是nil值昂儒,也就是Optional.None沟使,固然不能響應(yīng)后面的方法,所以就會(huì)跳過荆忍,如果有值格带,就是Optional.Some撤缴,可能就會(huì)拆包(unwrap)刹枉,然后對拆包后的值執(zhí)行后面的操作,比如:

let hashValue = strValue?.hashValue 

strValue是Optional的字符串屈呕,如果strValue是nil微宝,則hashValue也為nil,如果strValue不為nil虎眨,hashValue就是strValue字符串的哈希值

到這里我們看到了?的兩種使用場景:

聲明Optional值變量
用在對Optional值操作中蟋软,用來判斷是否能響應(yīng)后面的操作

另外,對于Optional值嗽桩,不能直接進(jìn)行操作岳守,否則會(huì)報(bào)錯(cuò):

//error: 'String?' does not have a member named 'hashValue'
//let hashValue = strValue.hashValue
//                ^        ~~~~~~~~~

let hashValue = strValue.hashValue

上面提到Optional值需要拆包(unwrap)后才能得到原來值,然后才能對其操作碌冶,那怎么來拆包呢湿痢?拆包提到了幾種方法,一種是Optional Binding, 比如:

if let str = strValue {
    let hashValue = str.hashValue
}

還有一種是在具體的操作前添加!符號(hào)譬重,這又是什么語法?!

例子拒逮,strValue是Optional的String:

let hashValue = strValue!.hashValue 

這里的!表示“我確定這里的的strValue一定是非nil的,盡情調(diào)用吧” 臀规,比如這種情況:

if strValue {
    let hashValue = strValue!.hashValue
}

{}里的strValue一定是非nil的滩援,所以就能直接加上!,強(qiáng)制拆包(unwrap)并執(zhí)行后面的操作塔嬉。 當(dāng)然如果不加判斷玩徊,strValue不小心為nil的話,就會(huì)出錯(cuò)谨究,crash掉佣赖。

考慮下這一種情況,我們有一個(gè)自定義的MyViewController類记盒,類中有一個(gè)屬性是myLabel憎蛤,myLabel是在viewDidLoad中進(jìn)行初始化。因?yàn)槭窃趘iewDidLoad中初始化纪吮,所以不能直接聲明為普通值:var myLabel : UILabel俩檬,因?yàn)榉荗ptional的變量必須在聲明時(shí)或者構(gòu)造器中進(jìn)行初始化,但我們是想在viewDidLoad中初始化碾盟,所以就只能聲明為Optional:var myLabel: UILabel?, 雖然我們確定在viewDidLoad中會(huì)初始化棚辽,并且在ViewController的生命周期內(nèi)不會(huì)置為nil,但是在對myLabel操作時(shí)冰肴,每次依然要加上!來強(qiáng)制拆包(在讀取值的時(shí)候屈藐,也可以用?,謝謝iPresent在回復(fù)中提醒)熙尉,比如:

myLabel!.text = "text"
myLabel!.frame = CGRectMake(0, 0, 10, 10)
...

對于這種類型的值联逻,我們可以直接這么聲明:var myLabel: UILabel!, 果然是高(hao)大(gui)上(yi)的語法!, 這種是特殊的Optional,稱為Implicitly Unwrapped Optionals, 直譯就是隱式拆包的Optional检痰,就等于說你每次對這種類型的值操作時(shí)包归,都會(huì)自動(dòng)在操作前補(bǔ)上一個(gè)!進(jìn)行拆包,然后在執(zhí)行后面的操作铅歼,當(dāng)然如果該值是nil公壤,也一樣會(huì)報(bào)錯(cuò)crash掉。

var myLabel: UILabel!  //!相當(dāng)于下面這種寫法的語法糖
var myLabel: ImplicitlyUnwrappedOptional<UILabel>

那么!大概也有兩種使用場景
1.強(qiáng)制對Optional值進(jìn)行拆包(unwrap)
2.聲明Implicitly Unwrapped Optionals值椎椰,一般用于類中的屬性

Swift是門新生的語言厦幅,我們有幸見證了它的誕生,激動(dòng)之余也在佩服蘋果大刀闊斧的推出一個(gè)新的語言替代一個(gè)已經(jīng)比較成熟語言的魄力慨飘,今天在知乎日報(bào)上看到一個(gè)回答是說Swift是一門玩具語言确憨,正當(dāng)想去吐槽,發(fā)現(xiàn)回答已經(jīng)被刪除了。個(gè)人認(rèn)為蘋果是很認(rèn)真的推出Swift的缚态,從Swift的各種細(xì)微的設(shè)計(jì)也能看的出來磁椒。

另外這兩個(gè)小符號(hào)就花費(fèi)了我不少的時(shí)間來理解,可能依然會(huì)有錯(cuò)誤和不妥之處玫芦,歡迎大家指正浆熔,本文旨在拋磚引玉。除此之外桥帆,Swift還有很多很棒的特性医增,WWDC 2014 會(huì)有四五個(gè)和Swift語言相關(guān)的Video,大家也可以去關(guān)注一下老虫。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末叶骨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子祈匙,更是在濱河造成了極大的恐慌忽刽,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件夺欲,死亡現(xiàn)場離奇詭異跪帝,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)些阅,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門伞剑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人市埋,你說我怎么就攤上這事黎泣。” “怎么了缤谎?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵抒倚,是天一觀的道長。 經(jīng)常有香客問我弓千,道長衡便,這世上最難降的妖魔是什么献起? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任洋访,我火速辦了婚禮,結(jié)果婚禮上谴餐,老公的妹妹穿的比我還像新娘姻政。我一直安慰自己,他們只是感情好岂嗓,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布汁展。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪食绿。 梳的紋絲不亂的頭發(fā)上侈咕,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音器紧,去河邊找鬼耀销。 笑死,一個(gè)胖子當(dāng)著我的面吹牛铲汪,可吹牛的內(nèi)容都是我干的熊尉。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼掌腰,長吁一口氣:“原來是場噩夢啊……” “哼狰住!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起齿梁,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對情侶失蹤催植,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后勺择,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體查邢,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年酵幕,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扰藕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡芳撒,死狀恐怖邓深,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情笔刹,我是刑警寧澤芥备,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站舌菜,受9級(jí)特大地震影響萌壳,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜日月,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一袱瓮、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爱咬,春花似錦尺借、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽虱歪。三九已至,卻和暖如春栅表,著一層夾襖步出監(jiān)牢的瞬間笋鄙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工怪瓶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留局装,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓劳殖,卻偏偏與公主長得像铐尚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子哆姻,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容