基本用法
switch 语句一定得是全覆盖的。就是说给定类型里的每一个值都得被考虑到并且匹配一个 case 语句,如果无法提供一个 switch-case 所有可能的值,就得定义一个默认的所有的 case 来匹配未明确给出的值。这个关键字用 default 标记,并且必须在所有的 case 的最后出现。(OC 里面的 switch 语句没有全覆盖代码也可以正常运行)
let c: Character = "z"
switch c {
case "a":
print("first letter of the alphabet")
case "z":
print("last letter of the alphabet")
default:
print("middle letter of the alphabet")
}
// 如果没有 default 语句的话会报错!
相比于 C 和 Objective-C 里面的 switch 语句,Swift 里的 switch 语句不会默认从匹配的 case 的末尾贯穿到下一个 case 语句里,而是会在匹配到第一个 case 执行完毕以后就退出,不需要显示的 break 语句。
如果要在一个 switch 的 case 中匹配多个值,可以用逗号隔开,并且写成多行:
let c: Character = "a"
switch c {
case "a", "A":
print("The letter A")
default:
print("Not the letter A")
}
// 控制台输出结果:
// The letter A
区间匹配
switch 的 case 的值可以在一个区间中匹配:
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).")
元组匹配
元组匹配:可以使用元组在一个 switch 语句中测试多个值,使用下划线_来表明匹配所有可能的值。
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 of the box")
default:
print("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}
// 控制台输出结果:
// (1, 1) is inside of the box
值绑定
switch 的 case 可以将匹配到的值历史绑定到一个常量或者变量上面来给 case 的函数体使用。
如果使用 var 关键字,临时变量就会以合适的值来创建并初始化。对这个变量的任何改变都只会在该 case 的函数体内生效。
let somePoint = (2, 0)
switch somePoint {
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
where 子句
switch case 可以使用 where 分句来检查是否符合特定的约束
let somePoint = (1, -1)
switch somePoint {
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
复合匹配
多种情形共享同一个函数体的多个情况可以在 case 后写多个模式来复合,在每个模式之间用逗号隔开。如果任何一个模式匹配了,那么这个情况都会被认为是匹配的。如果模式太长可以写成多行。
let c: Character = "e"
switch c {
case "a", "e", "i", "0", "u":
print("\(c) 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("\(c) is a consonant")
default:
print("\(c) is not a vowel or a consonant")
}
// 控制台输出结果:
// e is a vowel
复合匹配-值绑定
复合匹配可同样包含值绑定。所有复合匹配的模式都必须包含相同的值绑定,并且复合情况中的每一个绑定都得有相同类型的格式。这才能确保无论复合匹配的哪部分命中了,接下来的函数体中的代码都能访问到绑定的值并且值的类型也都相同。
let somePoint = (4, 0)
switch somePoint {
case (let distance, 0), (0, let distance):
print("On the axis, \(distance) from the origin")
default:
print("Not on the axis")
}
// 控制台输出结果:
// On the axis, 4 from the origin