iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 6
1
Software Development

Swift 菜鳥的30天系列 第 6

Day-06 Swift 語法(2) - 到底有沒有的 Optional 和 nil

前言

當初在學習這塊的時候常常不懂為什麼要在一些名稱之後加上 "!" 或是 "?" ,或是對於 nil 沒有值的意義, 當時被這兩者用途搞的模模糊糊,常常不小心把兩者的用法搞混在一起。因此我也要清楚的說明這兩者的分別,才不會讓閱讀的人產生誤會,也能讓自己複習一輪更清楚差別。

nil 空值

nil 代表的意思就是這個常數或變數中沒有值,但不是為 0 的意思, 0 也是值。

你可以在一開始就將值設定成沒有值的狀態,須在型別之後加上 "?",變數則可以在之後轉換成沒有值的狀態。
https://ithelp.ithome.com.tw/upload/images/20171225/20107701flfKaHdfdA.png

如果你定義的可選變量沒有提供一個默認值,變量會被自動設置成 nil

https://ithelp.ithome.com.tw/upload/images/20171225/20107701C6wJ4Ye0uu.png

  • nil 不能用於非可選的常數或者變數,如果你的程式碼中需要作用於特定條件下缺少的值,可以給他宣告為相對類型的可選項 (Optional)。*

Optional 可選項

大致上就是可以利用 Optional 來處理值可能缺失的情況。他代表了這個地方可能有值或是根本沒有值。其中 Optional 就是一個含有兩種情況的枚舉( enum ),枚舉裡有 None (沒有值)和 Some (有值) 兩種 case 。所以當我們希望宣告的變數或常數是一個沒有內容的時候,我們就可以使用到它。

宣告 Optional

我們可以在宣告一個變數或常數時,在它的型別後方加上一個 "?" 來表示他是一個 Optional 的變數常數。
https://ithelp.ithome.com.tw/upload/images/20171225/201077015D5ywCjHCQ.png

當然我們沒辦法宣告一個值為 nil 的常數或是變數,錯誤提示會告訴我們必須在 Int 後方加上一個 "?"。
https://ithelp.ithome.com.tw/upload/images/20171225/20107701YqUjCqLgzg.png

宣告 Optional 的過程,又稱為 Wrapped ,就像是被包起來的意思。

讀取 Optional

強制解包 (force-unwrap)

** 利用驚嘆號解開包裝讀取內容的方法稱為 force-unwrap , 就是強制解包。 **

在我們想要讀取 Optional 的值,我們必須在他後方加上一個 "!" 來 Unwrapped 他,因為我們前面在宣告他的時候就將它 wrapped 包裝起來,所以現在我們必須將它 Unwrapped 解開。

https://ithelp.ithome.com.tw/upload/images/20171225/201077012MCMGq7DAC.png

錯誤訊息也會告訴你還沒 unwrapped 這個 optional ,提示使用 "!" 修正他。

https://ithelp.ithome.com.tw/upload/images/20171225/20107701CUY0sNCeAi.png

但是如果原本我們的 box 裡面就是沒有值 ( nil )的話,使用強制解包就會發生錯誤,因為裡面原本就沒有值。
https://ithelp.ithome.com.tw/upload/images/20171225/20107701Ot1jgf3UfG.png

這時候我們可以使用其它方式來確認我們這個 optional 裏頭是否有值或是( nil )沒有值。

if 語法檢查 optional 是否有值

我們可以讓這個 optional 與 nil 進行比較,看 optional 的內容是否不等於沒有值( nil ) ,所以當我們的 box 的內容有值,他就會執行 "我的盒子裡有iPhone X " 這段程式碼,如果是沒有值,則執行 else 裡頭的程式碼。

https://ithelp.ithome.com.tw/upload/images/20171225/201077015vAp7KOEmY.png

判斷取值 (Optional Binding)

我們也可以 if let 一個常數來檢查 optional 裡面是否有值,如果有值一樣運行 "這個盒子裡有iPhone X " 這段程式碼,如果裡頭沒有值,則運行 else 裡面的 "這個盒子沒有東西" 。

https://ithelp.ithome.com.tw/upload/images/20171225/20107701sMwIK9aesa.png

你也可以使用相同的常數名稱去操作, Swift 允許我們在使用 optional binding 時,讓我們可以使用相同的常數名稱。舉例來說:
https://ithelp.ithome.com.tw/upload/images/20171225/201077014oOZLSB7OM.png

而 {} 中的 box 指的就是 if let 後的 box ,儲存著我們想從 optional 變數讀取的內容。

自動取值 (Implicitly Unwrapped Optional)

我們可以在一開始宣告的時候就在該常數或變數的型別後面加上 "!" ,讓程式自動來讀取他的值。
https://ithelp.ithome.com.tw/upload/images/20171225/20107701N4ZweHUcpP.png

*但是這種方式與我們上述的強制解包意思大同小異,如果當你這個變數或常數裡頭沒有值 (nil),那程式就會錯誤。

https://ithelp.ithome.com.tw/upload/images/20171225/20107701A8s30EHo09.png

當無值的時候,提供預設值

若希望在 Optional 沒有值的時後給預設值,可用雙問號 "??" 後面加預設值,讓程式在沒有值 (nil) 的時候給他一個預設值。

https://ithelp.ithome.com.tw/upload/images/20171225/20107701XLnwp1BZyu.png

https://ithelp.ithome.com.tw/upload/images/20171225/201077018AjqD1C1XL.png


上一篇
Day-05 Swift 語法(1) - 基本中的基本
下一篇
Day-07 Swift 語法(3) - 集合類型
系列文
Swift 菜鳥的30天30

尚未有邦友留言

立即登入留言