Alex Liang

Swift的?與!

在靜態語言中,nil or null的判斷是件重要卻常被忽略的事
當一個object或變數為null而沒被排除時,程式很有可能crash或出現莫明其妙的bug
Swift增加了optional幫助程式設計師避掉可能的crash,語法雖然簡單卻需要時間理解觀念

Optionals

當資料可能為nil時,我們在宣告變數時加入?。

1
2
3
4
5
var customerName: String? 		// nil
var regards = "Thank you! "
if let name = customerName { // skip
regards += name
}

當執行到if let時,因為customerName為nil而判斷式不會成立
沒有給定初始值的變數最好加上optional,在程式剛執行時還未給予值的情況下可避免crash

另一種情況是function的回傳值可能為nil時,使用optional會是合理的選擇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func findStore(storeName: String) -> String? {
storeList = ["7-11", "FamilyMarket", "Hi-life"]
for store in storeList {
if store == storeName {
return "Find \(storeName)!"
}
}

return nil
}

if let result = findStore("Poya") {
print(result)
}

findStore的回傳值為optionals,當storeList沒有符合的字串時則回傳nil
上例中result為nil,所以不會印出任何值

Unwrap

變數為optional時,使用!可以強制unwrap並存取資料

1
2
let result = findStore("7-11")			
result! // Find 7-11!

如上例,但此操作不符合官方的建議用法,同時也失去安全性

Downcast

當使用某些資料型態的值做為變數時,需要資料型態轉換。
如果不確定轉換是否成功,使用as?會回傳optional,如此可避免nil帶來的問題

1
2
3
4
5
6
7
8
9
10
11
12
13
let playlistDictionary = [
[
"title": "Native",
"artist": "OneRepublic"
]
[
"title": "V",
"artist": "Maroon 5"
]
]

let playlist = playlistDictionary[0]
let title = playlist["title"] as? String

當我們存取playlist的title時,由於不確定回傳的值是否為nil,所以使用as?做型態轉換

參考資料:
Type Casting官方文件