iT邦幫忙

2022 iThome 鐵人賽

DAY 3
0

什麼是Optional?

有了變數和常數,我們可以輕易儲存任何型別的資料。但在某些特別的情境,我們希望變數和常數能處於一個沒有內容的狀態。
為了處理無值的問題,我們可以用Optional的方式將其包裹起來。

Optional的宣告方式

//問號需緊連型別
var money: Int?

在這個例子中money可能是Int也有可能是nil。

不過就算有值,也是無法直接被取用的,Optional將變數包了起來(也就是說,被Optional包裝過的型別和原型別是不同的)

要將值取用,必須使用!

那如果變數裡的值是nil又使用!強制解析的話,系統會報錯

!是要能很確定內部值不是nil才能使用,如果是不確定的狀況,為了能安全的取得裡面的值,分別有幾種做法:

if 判斷

if value != nil { ... }

Optional Binding

也可以選擇把nil判斷跟取新變數的動作結合再一起

if let 新變數 = 舊變數 { ... }

跑出來的結果是完全相等的
如果不想要一直取新變數的話,新變數也可以取的跟舊的一樣

if let 舊變數 = 舊變數 { ... }

當然從print出來的結果就看得出來,雖然看起來一樣,但本質上還是取了新的變數

Optional Binding甚至能用於複數的變數,可以使用逗號分開

if let 新變數1 = 舊變數1, 新變數2 = 舊變數2 { ... }

當然還可以加上條件,一樣以逗號區隔

if let 新變數1 = 舊變數1, 新變數2 = 舊變數2...,其他條件 { ... }

Optional Chaining

有的時候想要取用物件的屬性或方法,但物件本身卻是Optional的,可以利用Optional Binding做檢查

if let 物件 = 物件 { 物件.屬性 ..... } 

但如果遇到比較多層的結構...

if let 物件 = 物件 { 
  if let 屬性1 = 物件.屬性1 { 
    屬性1 ..... 
  }
}
// 或是使用逗號
if let 物件 = 物件,
   let 屬性1 = 物件.屬性1 { 
     屬性1 ..... 
  }

這裡Swift給了一個方便的寫法

物件?.屬性1?.屬性2

也就是Swift會逐層檢查,,以上述例子來說,多層的 Optional Binding可以簡化為一層,而不需要再以多層 Optional Binding的方式檢查屬性了

另外由於 Optional需要包裹 nil以保持安全的原因,所以 Optional經過Optional Chaining還是會是 Optional,要使用還是需經過一次 unwrap

只要檢查到其中一層是空的就不會繼續檢查下去
這個語法不僅大大降低了巢狀結構的深度或是條件的複雜度,也提升了程式碼的可讀性,這裡的例子結構也偏簡單

if let 和 guard let 有什麼不一樣的地方?

既然有了 if let,為什麼還要生出一個 guard let 呢?在釐清這個問題時,應站在 guard let 其實是 if let 的進階版來思考這件事。 guard let 不僅在邏輯思維上與 if let 大不相同外,其 scope、可讀性也大不相同...

邏輯思維

guard 他的邏輯思維其實和 if let 是相反的。

Nil Coalescing Operator

如果想要以提供預設值的方法防止 crash,可以使用:??

optional ?? default

如果optional不為空時,使用左側內容,為空時使用default


上一篇
[鐵人賽 Day 02] Swift 基本型別
下一篇
[鐵人賽 Day 04] Swift 用 XIB 編寫 IOS
系列文
從零開始的IOS開發日常30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言