重讀 Swift 之一:Optional(可選型)

之前學(xué)習(xí) Swift 的時候都是比較破碎西采,零零散散,以至于有些地方學(xué)習(xí)的不夠透徹继控。所以趁最近有時間械馆,就開始重新學(xué)習(xí) Swift ,從最基本的開始學(xué)習(xí)武通,希望能深入理解霹崎,見微知著!
關(guān)于 Swift 我們都是到是類型安全型的冶忱,相較于 OC 尾菇,安全似乎更能體現(xiàn)出來。關(guān)于這一方面囚枪, Swift 的可選型(optional)就不得不說了派诬,可選型可以說是 Swift 最為突出的特性之一】衾可能有的同學(xué)在看 Swift 的過程中會遇到可選型(比如 String? )千埃,有時也會見到 String! 這樣的,搞不明白其中的意思忆植,所以今天就來一步步理解可選型放可。

一、什么是 Optional


Optional 是 Swift 新加入的類型朝刊,所以學(xué)過 OC 的童鞋就知道在 OC 中是沒有這個概念的耀里。可選型的意思簡單理解是:有值得時候就有值拾氓,無值的時候就是 nil 冯挎。Swift 中的 nil 和其他語言中的 nil 還有些不一樣,nil 自己本身就是一種類型咙鞍,沒有就是 nil 房官,是和其他類型嚴(yán)格區(qū)分開的趾徽。
可選型的定義很簡單:類型 + ? 。比如 String?翰守、Int?孵奶、Float? 等,這里需要注意的是 String?String 是完全不同的兩個類型蜡峰,前者是 String 類型的額可選型了袁,后者是 String 類型,注意區(qū)分湿颅。舉個例子载绿,在 OC 中我們可以這樣寫

 NSString *name = @"loveway";
 name = nil;

上面的這種寫法在 OC 中是沒有問題的,相比于上面油航,在 swift 中

var name: String = "loveway"
name = nil

如果我們像上面代碼中這樣寫就會報錯崭庸,如下

error

說的是 nil 是不可以分配給 String 類型的,這也說明在 swift 中 nil 是和其他類型嚴(yán)格區(qū)分的劝堪。改為可選型即可冀自,

var name: String? = "loveway"
name = nil

可選型揉稚,顧名思義就是可以選擇秒啦,比如 String? 的意思就是可以在 Stringnil 之間選擇,可以是 String 也可以是 nil 搀玖。如果一個變量定義成 String余境,那么這個變量就會是 String 類型,而不可能是nil灌诅。
還有一點需要注意的是聲明可選型必須是顯示的聲明也就是必須是

var name: String? = nil

這樣芳来,而不能是

var name = nil

這樣,因為 Swift 在做類型判斷的時候無法判斷 name 到底是 String 類型的可選型還是其他類型的可選型猜拾,因此會導(dǎo)致編譯錯誤即舌。

Tips: 當(dāng)然枚舉類型的寫法還可以如

var name: Optional<String> = Optional.Some("Loveway")

這樣,只不過我們一般都用

var name: String? = nil

這樣的簡寫挎袜。

二顽聂、Optional的解包


可選型是不能夠被直接使用的(因為 Swift 是類型安全的,可選型的值又可能會是 nil盯仪,如果不做處理可能導(dǎo)致程序 crash)紊搪,如果我們想使用可選型的值,那么在這之前我們需要做的一項工作就是:解包(unwarp)全景!

  • 1耀石、強制解包
    所謂的強制解包意思就是我知道這個類型是可選型,但是在我的程序執(zhí)行到這里的時候我可以保證它是有值得爸黄,所以我要在這里使用它滞伟。具體表現(xiàn)形式就是在可選型后面加個 !揭鳞,如下
var name: String? = "loveway"
"My name is " + name!

但是這樣的解包是不安全,因為你不知道什么時候你的這個可選型就會變成 nil梆奈,如果我們代碼非常多的話汹桦,一不小心為 nil了,可能會導(dǎo)致程序崩潰鉴裹。這個時候我們會想到一種方法:判空舞骆!如下,

var name: String? = "loveway"
if name != nil { 
   "My name is " + name!
} else {
    print("name is nil")
}

這樣寫似乎是沒有什么問題了径荔,但是需要注意的是督禽,你在判斷非 nil 的作用域內(nèi)使用 name 的時候還必須把 ! 帶上,這樣代碼比較多的時候還是比較麻煩总处。于是我們可以使用下面這種方式狈惫,

  • 2、使用 if let 解包
    使用 if let 解包如下鹦马,
var name: String? = "loveway"
if let name = name {
   "My name is " + name
} else {
    print("name is nil")
}

這種解包方式可以保證 name 是解包過的胧谈,不會再是 nil 這種情況,其實邏輯是和上面做非空判斷一樣的荸频。當(dāng)然你把 let 換成 var 也是可以的菱肖,效果是一樣的,只不過我們一般要用的是解包后的值旭从,而不會去改變它稳强,所以平常使用中一般都是用 if let
同時 if let 可以同時一次性解包多個可選型和悦,用 , 隔開退疫,使語句簡潔,如下

var name: String? = "loveway"
var age: Int? = 18
if let name = name, age = age {
   "My name is " + name
} else {
    print("name is nil")
}

最后鸽素,既然這里使用的是 if 褒繁,那么同樣我們可以如下這樣用,來進行進一步的判斷篩選

var name: String? = "loveway"
var age: Int? = 18
if let name = name, age = age where age == 18 {
    print("My name is \(name), age is \(String(age))")
} else {
    print("name is nil")
}

如上也是可以的馍忽。

三棒坏、可選鏈?zhǔn)秸{(diào)用(Optional Chaining)


可選鏈?zhǔn)秸{(diào)用(Optional Chaining)是一種可以在當(dāng)前值可能為 nil 的可選值上請求和調(diào)用屬性、方法及下標(biāo)的方法舵匾。如果可選值有值俊抵,那么調(diào)用就會成功,如果可選值是 nil 坐梯,那么調(diào)用將返回 nil徽诲。多個調(diào)用可以連接在一起形成一個調(diào)用鏈,如果其中任何一個節(jié)點為 nil ,整個調(diào)用鏈都會失敗谎替,即返回 nil 偷溺。
下面我們就來舉個例子具體說明可選鏈,如下

var name: String? = "loveway"
if let name = name {
    print(name.uppercaseString)
} else {
    print("name is nil")
}

我們來解包 name 钱贯,如果有值就打印出 name 的大寫挫掏,如果沒有就輸出 name is nil ,其實上面這段代碼完全等同于

var name: String? = "loveway"
name?.uppercaseString

上面這句代碼的意思就是如果可選型變量 name 有值秩命,那么就對 name 進行解包尉共,并得到 name 的uppercaseString 值,如果沒有弃锐,那么這句代碼就會返回一個 nil 袄友。這樣就符合 Swift 的類型安全,完全是沒有問題的霹菊。但是如果你寫成

var name: String? = "loveway"
name!.uppercaseString

也是可以的剧蚣,不過不安全,因為如果 name 沒有值旋廷,你進行強制解包鸠按,就會報錯。
所以我們以后可能會用到類似于 person?.name?.uppercaseString 這樣的一層層解包的饶碘,這種就是可選鏈目尖。

四、Nil Coalescing Operator(空合運算符)


如上熊镣,如果我們想把解包后的值存起來的話卑雁,可以這樣

let newName = name == nil ? "no name" : name!

上面代碼的意思就是如果 name 為 nil 募书,newName 就是 "no name"绪囱,否則 newName 就是 name!(name的解包)。其實 Swift 為我們提供了更簡潔的語法莹捡,如下

let newName2 = name ?? "no name"

上面代碼的意思就是 name 如果有值 newName2 的值就是 name! ,否則就是 no name 鬼吵。這里需要注意的是 ??是空合運算符,這樣寫的可閱讀性強篮赢,比較簡潔齿椅。
當(dāng)然關(guān)于 ?? 遠不止這些,有興趣的同學(xué)可以看 聊聊swift語言中的“??” 這篇文章启泣。

五涣脚、隱式可選型


上面我們都知道了,創(chuàng)建一個顯示可選型是: 類型 + ?寥茫。這里創(chuàng)建隱式可選型的就是: 類型 + !遣蚀。

var name: String! = "loveway"

這里可能有的童鞋會疑惑,已經(jīng)有了顯示的可選型,為什么還需要有隱式的可選型芭梯。這里其實隱式的可選型也是有一定作用的险耀。比如你有一個變量,聲明為隱式的可選型(!)玖喘,它的作用就是甩牺,當(dāng)你這個類沒有被初始化的時候他是沒有值的,但是當(dāng)你這個類初始化以后累奈,你可以確保他是有值的贬派,所以這里聲明為隱式的可選型,而不是顯示的澎媒。同樣需要注意的是隱式的可選型也是可選型赠群,如果你需要用它的值,你也是要進行判斷的旱幼。如果不進行判斷而直接使用查描,可能會造成不可預(yù)料的后果!
差不多可選型就到這里了柏卤,如果還有什么遺漏冬三,歡迎大家指正!

參考鏈接:可選鏈?zhǔn)秸{(diào)用(Optional Chaining)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末缘缚,一起剝皮案震驚了整個濱河市勾笆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌桥滨,老刑警劉巖窝爪,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異齐媒,居然都是意外死亡蒲每,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門喻括,熙熙樓的掌柜王于貴愁眉苦臉地迎上來邀杏,“玉大人,你說我怎么就攤上這事唬血⊥” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵拷恨,是天一觀的道長脖律。 經(jīng)常有香客問我,道長腕侄,這世上最難降的妖魔是什么小泉? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任勒叠,我火速辦了婚禮,結(jié)果婚禮上膏孟,老公的妹妹穿的比我還像新娘眯分。我一直安慰自己,他們只是感情好柒桑,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布弊决。 她就那樣靜靜地躺著,像睡著了一般魁淳。 火紅的嫁衣襯著肌膚如雪飘诗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天界逛,我揣著相機與錄音昆稿,去河邊找鬼。 笑死息拜,一個胖子當(dāng)著我的面吹牛溉潭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播少欺,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼喳瓣,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了赞别?” 一聲冷哼從身側(cè)響起畏陕,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎仿滔,沒想到半個月后惠毁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡崎页,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年鞠绰,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片实昨。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡洞豁,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出荒给,到底是詐尸還是另有隱情,我是刑警寧澤刁卜,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布志电,位于F島的核電站,受9級特大地震影響蛔趴,放射性物質(zhì)發(fā)生泄漏挑辆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鱼蝉。 院中可真熱鬧洒嗤,春花似錦、人聲如沸魁亦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽洁奈。三九已至间唉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間利术,已是汗流浹背呈野。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留印叁,地道東北人被冒。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像轮蜕,于是被迫代替她去往敵國和親姆打。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

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