對 Swift 中可選類型的理解

一惩琉、類型定義

OC 中哮独,我們可以這樣定義一個變量:

int a = 0;

也可以這樣定義:

int a;

這兩種定義的方式都是一樣的,這里的 一樣 是指 是一樣的洼滚。第二種方式雖然沒有顯式的指定其值埂息,但是會默認(rèn)設(shè)置一個 0
如果在開發(fā)的過程中,我們一定要對這兩種情況做區(qū)分千康,應(yīng)該怎么處理呢享幽?畢竟沒有賦值與默認(rèn)設(shè)置一個初始值,還是有所區(qū)別的拾弃。在 OC 中沒有專門的語法支持值桩,當(dāng)然也是能實現(xiàn)的,只是需要額外的變量來做輔助豪椿,特別的麻煩奔坟。

OC 中不行,但是在 Swift 中就顯得小菜一碟了搭盾。多了一種 可選 類型咳秉。什么叫可選類型呢?

一個變量沒有默認(rèn)值這一說鸯隅,要么有值澜建,要么沒有值。 這就叫做可選類型蝌以。

提示:

Swift 中的可選類型炕舵,是一種單獨的數(shù)據(jù)類型。有可選類型饼灿,那么就有非可選類型幕侠。

定義有如下三種方式:
var a:Optional<Int>
var b:Int?
var c:Int!
以上的 a帝美,b碍彭,c 都是可選類型。

但是這兩三種定義的方式悼潭,也是有異同的庇忌,后面再做介紹。

二舰褪、如何標(biāo)識有值與妹紙

上面說了皆疹,可選類型的變量,主要針對的是有值還是沒有值占拍,兩種狀態(tài)略就。那么如何來標(biāo)識呢?

首先來認(rèn)識一下 OC 中的 nil晃酒。代表的是一個空指針表牢,或者是默認(rèn)指針的值,或者是手動賦值為 nil贝次〈扌耍總之,給一個指針賦值為 nil, 代表的是一個空值敲茄,是一個具體的空值位谋。

但是在 Swift 中就不一樣了。只能給一個可選類型的變量賦值為 nil堰燎,一旦賦值為 nil掏父,那么就代表是當(dāng)前可選類型的變量就為沒有值的狀態(tài)。這里有點繞秆剪,并不是說當(dāng)前的變量為 nil损同,而是一種狀態(tài)而已。換句話說鸟款,當(dāng)給一個可選類型賦值為nil的時候膏燃,并不是將 nil給當(dāng)前的變量,而是將當(dāng)前的變量變成一個 沒有值 的狀態(tài)何什。

同時也要注意這里強(qiáng)調(diào)的是可選類型组哩,沒有說指針。所以可選類型可以是基本數(shù)據(jù)類型处渣,也可以是所謂的指針伶贰。

接著上面的定義:

var a:Optional<Int>
var b:Int?
var c:Int!

以上的三個都是可選類型的變量。在定義可選類型的時候罐栈,不給賦值黍衙,那么當(dāng)前的可選類型的變量就屬于沒有值的狀態(tài)。那么問題來了荠诬,那他到底是什么值呢琅翻?

答案是 沒有值 的狀態(tài),說明當(dāng)前變量屬于一個沒有值的狀態(tài)柑贞。

說了半天的可選類型方椎,那么非可選類型的又是怎么樣的呢?

var b:Int

上面這句代碼钧嘶,在 Swift 中是不能通過的棠众。因為這是一個非可選類型的變量,非可選類型的變量有决,每時每刻都必需要保證有值闸拿。比如這樣的:

image.png

接下來看一個變量的有值與沒有值之間的轉(zhuǎn)換:

// 定義一個可選類型的變量
// 當(dāng)前的 e, 是沒有值的狀態(tài)
var e:Int?

// 當(dāng)前的 e, 是有值的狀態(tài)
e = 3

// 當(dāng)前的 e, 變成了一個沒有值的狀態(tài)
e = nil

三、獲取可選類型的值

3.1 獲取可選類型的值(上)

可選類型书幕,是一個單獨的數(shù)據(jù)類型新荤。對于賦值來說,與我們熟悉的賦值沒有任何區(qū)別按咒,是一個 Int 類型的值迟隅,直接給一個數(shù)字就可以了但骨,其它類型的類似。但是取值智袭,就有點不一樣了奔缠。
看一下下面的打印結(jié)果:


image.png

可以看出,實際的值被一個 Optional 包起來了吼野。再來看一下這個:

image.png

直接報錯了校哎,說明可選類型的是不能直接使用的。那應(yīng)該如何去獲取呢瞳步?
在上圖的報錯中闷哆, 就已經(jīng)有提示了,正確的獲取方式是:

print(e! + 3)

一般在 可選類型的后面加一個 单起! 就可以了抱怔。但是這只是其中的一種情況,具體的放在后面介紹嘀倒。在上面也介紹了屈留,可選類型是一種獨立的類型,只是每種可選類型肯定是對應(yīng)著某種特定的數(shù)據(jù)類型测蘑。我們對可選類型的取值灌危,主要的目的就是獲取當(dāng)前可選類型中的特定數(shù)據(jù)類型的值。

3.2 獲取可選類型的值(下)

上面簡單的介紹了碳胳。對于一個可選類型變量的取值勇蝙,是需要做一些處理的,不能直接獲取挨约。接下來的問題是:

對于可選類型變量的取值味混,應(yīng)該注意些什么呢?

image.png

說明烫罩,對于一個可選類型的變量來說惜傲,如果當(dāng)前的變量為 沒有值 的狀態(tài),還去獲取值的話贝攒,這是不允許的,直接報錯时甚。

3.3 獲取可選類型的值(終)

從上面的分析可以得出隘弊,獲取可選類型的值,一定要保證當(dāng)前可選類型變量處于有值的狀態(tài)荒适,否則直接報錯梨熙。細(xì)心想想也對,盡然當(dāng)前的變量的狀態(tài)就是一個沒有值的狀態(tài)了刀诬,你還要去取值咽扇,這不是找死么?

那么問題又來了: 我們應(yīng)該如何去獲取可選類型的值呢? 關(guān)于這個問題,我們主要是圍繞著 只會在有值的狀態(tài)下质欲,才去解包取值树埠。

3.3.1 if 取值法
// if 取值法
if e != nil {
    print(e! + 3)
}

意思就是先判斷 e 是否不為 nil, 如果不為 nil, 那么就強(qiáng)制解包取值嘶伟。

3.3.2 綁定取值
// 綁定取值
if let e_value = e  {
    print(e_value + 3)
}

這種方式比第一種方式方便了很多怎憋,直接通過 if 判斷當(dāng)前的 e 是否有值,如果有值,則直接強(qiáng)制解包為 e_value, 如果沒有值僧界,那么當(dāng)前的 if 條件不成立艾恼。

3.3.3 guard取值
// 函數(shù)
func hgFunc(e:Int?) {
    guard let e_guard_value = e else {
        print("e 當(dāng)前沒有值")
        return
    }
    print(e_guard_value)
}

函數(shù) hgFunc 中的參數(shù)是一個可選類型,所以在使用的的時候可定需要做判斷荸镊。但是這個 guardif 很相似,同時也還有很大的不同。仔細(xì)觀察會發(fā)現(xiàn)规个,括號中執(zhí)行的條件是 為 false 的情況下才會執(zhí)行。還有一個更明顯的特點是 e_guard_value 這個變量姓建,在 e_guard_value的括號外面還能有效诞仓。如果使用 if 的話,還需要額外的聲明一個變量速兔。

3.3.4 雙問號取值
// 如果 e 有值, 則獲取 e 中的值
// 沒有值, 則賦值為5
let e_value = e ?? 5

// 所以 e_value 值要么是 e 中的值
// 要么是 5
print(e_value)

這種方式也比較的直觀墅拭,能很好的處理一些一定要保證能獲取一個有效值的情況。

四涣狗、說在后面的話

是的谍婉,對于可選類型,我暫時就理解到這里了镀钓。在 Swift 開發(fā)中穗熬,使用得最多的即使可選類型的變量,所以理解好可選類型是很關(guān)鍵的一步丁溅。當(dāng)然唤蔗,主要是理解好,并在不同的場景使用好才是最關(guān)鍵的窟赏。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末妓柜,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子涯穷,更是在濱河造成了極大的恐慌棍掐,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件拷况,死亡現(xiàn)場離奇詭異作煌,居然都是意外死亡掘殴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進(jìn)店門粟誓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奏寨,“玉大人,你說我怎么就攤上這事努酸》” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵获诈,是天一觀的道長仍源。 經(jīng)常有香客問我,道長舔涎,這世上最難降的妖魔是什么笼踩? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮亡嫌,結(jié)果婚禮上嚎于,老公的妹妹穿的比我還像新娘。我一直安慰自己挟冠,他們只是感情好于购,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著知染,像睡著了一般肋僧。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上控淡,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天嫌吠,我揣著相機(jī)與錄音,去河邊找鬼掺炭。 笑死辫诅,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的涧狮。 我是一名探鬼主播炕矮,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼勋篓!你這毒婦竟也來了吧享?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤譬嚣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后钞它,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拜银,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡殊鞭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了尼桶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片操灿。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖泵督,靈堂內(nèi)的尸體忽然破棺而出趾盐,到底是詐尸還是另有隱情,我是刑警寧澤小腊,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布救鲤,位于F島的核電站,受9級特大地震影響秩冈,放射性物質(zhì)發(fā)生泄漏本缠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一入问、第九天 我趴在偏房一處隱蔽的房頂上張望丹锹。 院中可真熱鬧,春花似錦芬失、人聲如沸楣黍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽租漂。三九已至,卻和暖如春垢啼,著一層夾襖步出監(jiān)牢的瞬間窜锯,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工芭析, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留锚扎,地道東北人。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓馁启,卻偏偏與公主長得像驾孔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子惯疙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

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