For-In 循環(For-In Loops)
- 如果不需要知道區間序列內每一項的值,你可以使用下劃線(_)替代變量名來忽略對值的訪問:
let base = 3
let power = 10
var answer = 1
for _ in 1...power {
answer *= base
}
print("\(base) to the power of \(power) is \(answer)")
// 輸出 "3 to the power of 10 is 59049"
While 循環(While Loops)
- Swift語言的repeat-while循環合其他語言中的do-while循環是類似的。
repeat {
statements
} while condition
Switch
- switch語句必須是完備的。這就是說,每一個可能的值都必須至少有一個 case 分支與之對應。在某些不可能涵蓋所有值的情況下,你可以使用默認(default)分支滿足該要求,這個默認分支必須在switch語句的最后面。
- 與 C 語言和 Objective-C 中的switch語句不同,在 Swift 中,當匹配的 case 分支中的代碼執行完畢后,程序會終止switch語句,而不會繼續執行下一個 case 分支。這也就是說,不需要在 case 分支中顯式地使用break語句。
- 一個 case 也可以包含多個模式,用逗號把它們分開(如果太長了也可以分行寫):
- case 分支的模式也可以是一個值的區間。
- 可以使用元組在同一個switch語句中測試多個值。元組中的元素可以是值,也可以是區間。另外,使用下劃線(_)來匹配所有可能的值。
- case 分支的模式允許將匹配的值綁定到一個臨時的常量或變量,這些常量或變量在該 case 分支里就可以被引用了——這種行為被稱為值綁定(value binding)。
- case 分支的模式可以使用where語句來判斷額外的條件。
let someCharacter: Character = "e"
switch someCharacter {
case "a", "e", "i", "o", "u":
print("\(someCharacter) is a vowel")
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
"n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
print("\(someCharacter) is a consonant")
default:
print("\(someCharacter) is not a vowel or a consonant")
}
// 輸出 "e is a vowel"
let approximateCount = 62
let countedThings = "moons orbiting Saturn"
var naturalCount: String
switch approximateCount {
case 0:
naturalCount = "no"
case 1..<5:
naturalCount = "a few"
case 5..<12:
naturalCount = "several"
case 12..<100:
naturalCount = "dozens of"
case 100..<1000:
naturalCount = "hundreds of"
default:
naturalCount = "many"
}
print("There are \(naturalCount) \(countedThings).")
// 輸出 "There are dozens of moons orbiting Saturn."
let somePoint = (1, 1)
switch somePoint {
case (0, 0):
print("(0, 0) is at the origin")
case (_, 0):
print("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
print("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
print("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
print("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}
// 輸出 "(1, 1) is inside the box"
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"
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"
控制轉移語句(Control Transfer Statements)
- 當一個switch分支僅僅包含注釋時,會被報編譯時錯誤。注釋不是代碼語句而且也不能讓switch分支達到被忽略的效果。你總是可以使用break來忽略某個分支。
let numberSymbol: Character = "三" // 簡體中文里的數字 3
var possibleIntegerValue: Int?
switch numberSymbol {
case "1", "?", "一", "?":
possibleIntegerValue = 1
case "2", "?", "二", "?":
possibleIntegerValue = 2
case "3", "?", "三", "?":
possibleIntegerValue = 3
case "4", "?", "四", "?":
possibleIntegerValue = 4
default:
break
}
if let integerValue = possibleIntegerValue {
print("The integer value of \(numberSymbol) is \(integerValue).")
} else {
print("An integer value could not be found for \(numberSymbol).")
}
// 輸出 "The integer value of 三 is 3."
- 如果你確實需要 C 風格的貫穿的特性,你可以在每個需要該特性的 case 分支中使用fallthrough關鍵字。如果不是必須,一般不要這么做。
提前退出(Early Exit)
可以使用guard語句來要求條件必須為真時,以執行guard語句后的代碼。一個guard語句總是有一個else分句,如果條件不為真則執行else分句中的代碼。
相比于可以實現同樣功能的if語句,按需使用guard語句會提升我們代碼的可靠性。它可以使你的代碼連貫的被執行而不需要將它包在else塊中,它可以使你處理違反要求的代碼接近要求。這個功能推薦使用。
func greet(person: [String: String]) {
guard let name = person["name"] else {
return
}
print("Hello \(name)")
guard let location = person["location"] else {
print("I hope the weather is nice near you.")
return
}
print("I hope the weather is nice in \(location).")
}
greet(["name": "John"])
// 輸出 "Hello John!"
// 輸出 "I hope the weather is nice near you."
greet(["name": "Jane", "location": "Cupertino"])
// 輸出 "Hello Jane!"
// 輸出 "I hope the weather is nice in Cupertino."
檢測 API 可用性(Checking API Availability)
if #available(iOS 9, OSX 10.10, *) {
// 在 iOS 使用 iOS 9 的 API, 在 OS X 使用 OS X v10.10 的 API
} else {
// 使用先前版本的 iOS 和 OS X 的 API
}
這種用法推薦使用,就用這個經典結構,隨時兼容最新的iOS特性