對於一個 iOS 開發者來說,最常做的開發任務就是在 Swift 中 Unwrap Optional 變數 (variable)。
Unwrap 也是面試中最常出現的問題。
在這篇文章中,我會介紹一個在 Swift 5.7 中為 Unwrap 而設的小「語法糖 (syntactic sugar)」 。這個改變並不是這篇文章的重點,更重要的是這個題目的討論。
在深入討論這個題目之前,我們首先要了解什麼是 Shadowing。
Shadowing 是一個壞的做法嗎?
我們都一定遇過這個情況。
假設我們想要 unwrap 一個 optional 變數。
var x: Int?
if let x = x {
// do something with the new x
}
在 unwrap optional 變數 x 的時候,我們會創建一個新的同名常數 x,當中包含同樣的數值,而我們會使用這個常數,而不會使用 optional 變數。
這個動作就是 Shadowing,因為新的常數就像是我們原本想 unwrap 的 optional 的影子。
Shadowing 是一個好的做法嗎?
其實 Shadowing 一個 optional 變數的確會引起一些問題。
首先,以上的例子無法反映現實情況。
變數的名稱通常是更長的。
舉個例子:
var lastTimeUserEnteredTheApp: Date?
if let lastTimeUserEnteredTheApp = lastTimeUserEnteredTheApp {
// do something with the new variable
}
以上這個例子中,變數的名稱很長。我們了解到如果 optional 變數名稱很長的話,unwrap 時的程式碼也會變得很長,這樣就會很奇怪。
那我們該怎麼做呢?讓我們試試把名稱縮短吧!
var lastTimeUserEnteredTheApp: Date?
if let date = lastTimeUserEnteredTheApp {
// do something with the new variable
}
好,我們把名稱縮短為 date,但這樣,date 的意思就不夠清楚了。要編寫出可讀的程式碼,名稱是十分重要的,因此我們需要深思如何命名 optional 變數。
那讓我們回到 Shadowing(保留變數原本的名稱),又會發現另一個新問題,就是有兩個名稱相同的變數。當然,我們都是專業的,要處理這個問題並不難,但那畢竟不是最好的方法。
雖然我們都在用 Shadowing,但其實這個方法也有其缺點。
而現在,Swift 5.7 就有一個有趣的新方法,來處理這個情況。
不過,這個方法又可能會引起新的問題,讓我們深入研究一下吧!
縮短 Shadowing
解決方法十分簡單。我們之前會這樣編寫程式碼:
var x: Int?
if let x = x {
// do something with the new x
}
現在可以改成這樣:
if let x {
// do something with the new x
}
如果變數名稱太長的話,這個解決方法十分方便:
if let lastTimeUserEnteredTheApp {
// do something
}
當然,這個解決方法也需要另一個 Shadowing unwrap:
guard let lastTimeUserEnteredTheApp else {return}
但這個方法也不是完美的。
有些人說 Swift 5.7 這樣縮短的方法也有缺點。
舉個例子,在執行以下程式碼時:
if var x {
}
如此一來,x 的 context 其實更加含糊不清,感覺 x 是一個沒有數值的新變數。而 “= x” 其實為我們提供了 context,並反映我們使用的是一個現有變數。
另一個缺點的影響可能更大。
我們說 Shadowing 未必是一個好的辦法,因為這樣會創建出重覆的變數。
但 Swift 5.7 這個解決方法,根本無法讓我們避免使用 Shadowing。這個方法甚至讓我們更加偏向使用 Shadow optional 變數,讓我們更加陷入深淵。
我的想法
作為一個「老」開發者,我覺得要縮短 unwrap 的程式碼十分困難,所以我的闡述未必是一個好例子。
但我覺得這個 Swift 5.7 的新功能,可以讓我們思考命名、重覆的變數、和程式碼的可讀性等問題。
你有什麼想法呢?你喜歡這個新功能嗎?