版本
Xcode 11.0
Swift 5.1
控制流
類似於其他語言, Switch中控制流關鍵字有:
- if
- guard
- while
- repeat-while
- for (Swift 3開始遺棄, 使用for-in區間遍歷)
- for-in
- switch
注: guard 的執行取決於一個表達式的布爾值, 類似於 if, 表過不提; repeat-while 類似於 do-while.
控制轉移語句改變你代碼的執行順序,通過它可以實現代碼的跳轉。Swift 有五種控制轉移語句:
- continue
- break
- fallthrough
- return
- throw
注: 使用 fallthrough 關鍵字來“貫穿”跳轉到下一個分支中; 使用 throw 來處理和拋出錯誤.
基於這些關鍵字的已知性/常用性/存異性, 下面挑選 for-in 和 switch 進行討論.
for-in
let nameList = ["小黑", "小紅", "小白", "小綠", "小藍"]
// 全部遍歷
for name in nameList {
print(name)
}
/*
小黑
小紅
小白
小綠
小藍
*/
// 區間遍歷1 (全閉)
for index in 1...3 {
print("\(nameList[index]) 的序號是 \(index)")
}
/*
小紅 的序號是 1
小白 的序號是 2
小綠 的序號是 3
*/
// 區間遍歷2 (左閉右開)
for index in 1..<3 {
print("\(nameList[index]) 的序號是 \(index)")
}
/*
小紅 的序號是 1
小白 的序號是 2
*/
// 區間遍歷3 (另一種寫法)
for name in nameList[2...] { // 從下標2遍歷到末尾
print(name)
}
/*
小白
小綠
小藍
*/
// 區間遍歷4 (倒序)
for index in (1...3).reversed() {
print("\(nameList[index]) 的序號是 \(index)")
}
/*
小綠 的序號是 3
小白 的序號是 2
小紅 的序號是 1
*/
如果你不需要區間序列內每一項的值,你可以使用下劃線(_)替代變量名來忽略這個值:
for _ in 1...3 {
print("repeat")
}
/*
repeat
repeat
repeat
*/
switch
1. 不必用 break
與 C 和 Objective-C 中的 switch 語句不同,在 Swift 中,當匹配的 case 分支中的代碼執行完畢後,程序會終止 switch 語句,而不會繼續執行下一個 case 分支。這也就是說,不需要在 case 分支中顯式地使用 break 語句。當然你依然可以在 case 分支中的代碼執行完畢前使用 break 跳出。
let age = 18
switch age {
case 18:
print("小鮮肉")
default:
print("老臘肉")
}
// 打印 小鮮肉
2. default必須放在最後
假如 default 之後還有 case , 那麼編譯的時候就會報錯.
3. 不能兩個case連用
switch 語句必須是完備的。這就是說,每一個可能的值都必須至少有一個 case 分支與之對應。
下面兩個 case 連用, 報錯:
switch age {
case 18:
case 22:
print("小鮮肉")
default:
print("老臘肉")
}
// 報錯, 因爲case 18:後面沒有代碼句
如果需要同時匹配兩個或兩個以上條件, 使用","將它們分隔.
正解如下:
switch age {
case 18, 22, 25:
print("小鮮肉")
default:
print("老臘肉")
}
// 打印 小鮮肉
4. 區間匹配
switch age {
case 18...25:
print("小鮮肉")
default:
print("老臘肉")
}
// 打印 小鮮肉
5. 兩個 case 均匹配, 只執行第一個
switch age {
case 18, 22, 25:
print("小鮮肉1")
case 18...25:
print("小鮮肉2")
default:
print("老臘肉")
}
// 打印 小鮮肉1
6. switch 中使用元組
我們可以使用元組在同一個 switch 語句中測試多個值。元組中的元素可以是值,也可以是區間。另外,使用下劃線(_)來匹配所有可能的值。
let somePoint = (1, 1)
switch somePoint {
case (0, 0):
print("\(somePoint) is at the origin")
case (_, 0):
print("\(somePoint) is on the x-axis")
case (0, _):
print("\(somePoint) is on the y-axis")
case (-2...2, -2...2):
print("\(somePoint) is inside the box")
default:
print("\(somePoint) is outside of the box")
}
// 輸出“(1, 1) is inside the box”
7. 綁定值
case 分支允許將匹配的值聲明爲臨時常量或變量,並且在 case 分支體內使用 —— 這種行爲被稱爲值綁定(value binding),因爲匹配的值在 case 分支體內,與臨時的常量或變量綁定。
let anotherPoint = (2, 0)
switch anotherPoint {
case (let x, 0):
print("on the x-axis with an x value of \(x)")
case (0, let y):
print("on the y-axis with a y value of \(y)")
case let (x, y):
print("somewhere else at (\(x), \(y))")
}
// 輸出“on the x-axis with an x value of 2”
8. where
case 分支的模式可以使用 where 語句來判斷額外的條件。
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
print("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
print("(\(x), \(y)) is on the line x == -y")
case let (x, y):
print("(\(x), \(y)) is just some arbitrary point")
}
// 輸出“(1, -1) is on the line x == -y”
檢測API可用性
if #available(平臺名稱 版本號, ..., *) {
APIs 可用,語句將執行
} else {
APIs 不可用,語句將不執行
}
// 例如
if #available(iOS 10, macOS 10.12, *) {
// 在 iOS 使用 iOS 10 的 API, 在 macOS 使用 macOS 10.12 的 API
} else {
// 使用先前版本的 iOS 和 macOS 的 API
}