Swift 控制流
程序默认从上往下执行,但真实业务里你需要"做判断"(条件分支)和"重复做事"(循环)。Swift 的控制流设计简洁而强大,本章讲透 if、guard、switch、for-in、while 五个核心语句。
1. if / else if / else
最基础的条件语句。Swift 的 if 和其他语言几乎一样,但有两个细节:条件必须是 Bool(不能是 0/1),以及条件里可以直接声明变量(配合可选解包,下面单独讲):
let score = 78
// 简单 if
if score >= 60 {
print("及格")
}
// if - else
if score >= 90 {
print("优秀")
} else {
print("还得努力")
}
// if - else if - else
if score >= 90 {
print("A")
} else if score >= 80 {
print("B")
} else if score >= 60 {
print("C")
} else {
print("D")
}
// 条件里可以直接声明变量(Swift 特色)
if let input = readLine(), let n = Int(input) {
print("你输入了 \(n)")
}2. guard:Swift 的"提前退出"哲学
guard 是 Swift 独有的语句,作用是"检查一个条件,不满足就退出"。它解决了 if-let 嵌套地狱,让主流程保持扁平:
// guard:提前退出,让主流程扁平
func process(input: String?) {
// 传统写法:if-let 嵌套
// if let s = input {
// if let n = Int(s) {
// if n > 0 { print(n) }
// }
// }
// guard 写法:错误情况先 return
guard let s = input else {
print("输入为空")
return
}
guard let n = Int(s) else {
print("不是数字")
return
}
guard n > 0 else {
print("必须正数")
return
}
// 主流程里直接用 n(已解包)
print("合法输入: \(n)")
}
process(input: "42") // 合法输入: 42
process(input: nil) // 输入为空guard 的几个要点:
- else 分支必须离开当前作用域:
return、continue、break、throw、fatalError()都行。 - guard let 解包的变量在作用域剩余部分可用——这是它比 if-let 优雅的核心。
- Swift 社区强烈推荐"早返回"风格:函数开头用 guard 把所有前置条件检查完,再写主逻辑。
3. switch:同类语言里最强大的
Swift 的 switch 是同类语言里最强大的之一。三个独有特性:不贯穿(不需要 break)、必须穷尽(或加 default)、支持模式匹配:
// Swift 的 switch:强大的模式匹配
let level = "B"
switch level {
case "A":
print("优秀")
case "B": // 单值匹配
print("不错")
case "C", "D": // 多值合并
print("及格")
default:
print("未知")
}
// 1. 不需要写 break,匹配后自动结束(不会贯穿)
// 2. 必须穷尽所有可能,或加 default
// 3. 想贯穿用 fallthrough(极少用)
// 区间匹配
let score = 78
switch score {
case 90...100: print("A")
case 80..<90: print("B")
case 60..<80: print("C")
default: print("D")
}
// 元组匹配 + 值绑定
let point = (2, 0)
switch point {
case (0, 0):
print("原点")
case (_, 0): // _ 表示"任意"
print("x 轴")
case (0, _):
print("y 轴")
case (let x, let y): // 值绑定
print("其他点 \(x), \(y)")
}
// where 子句
let age = 18
switch age {
case 0...17: print("未成年")
case 18...65 where age != 18: print("成年人")
case 18: print("刚成年")
default: print("老年")
}它支持单值匹配、多值合并、区间匹配、元组匹配、值绑定、where 子句——几乎无所不能。如果你写过 Rust 或 Scala,会觉得熟悉;如果你从 Java 来,会发现 Swift 的 switch 既是 if-else 的替代,也是模式匹配工具。
4. for-in:唯一的 for 循环
Swift 没有 C 风格的 for (int i=0; i<n; i++)。所有循环用 for-in 配合范围、stride、数组、字典:
// for-in:Swift 唯一的 for 循环(没有 C 风格 for)
// 闭范围
for i in 1...5 {
print(i) // 1 2 3 4 5
}
// 半开范围
for i in 0..<3 {
print(i) // 0 1 2
}
// 不需要索引时,用下划线忽略
for _ in 1...3 {
print("ping") // ping ping ping
}
// 跳步 stride
for i in stride(from: 0, to: 10, by: 2) {
print(i) // 0 2 4 6 8
}
for i in stride(from: 10, through: 0, by: -2) {
print(i) // 10 8 6 4 2 0
}
// 遍历数组
let fruits = ["apple", "banana", "cherry"]
for fruit in fruits {
print(fruit)
}
// 同时拿到索引和值
for (i, fruit) in fruits.enumerated() {
print("\(i): \(fruit)")
}
// 遍历字典
let scores = ["小明": 90, "小红": 85]
for (name, score) in scores {
print("\(name): \(score)")
}几个高频技巧:不需要索引时用 _ 忽略;跳步用 stride;遍历数组要索引用 .enumerated();遍历字典直接解构 (key, value)。
5. while 与 repeat-while
- while 条件:先判后执行,可能一次都不跑。
- repeat { } while 条件:先执行一次再判(相当于 C 的 do-while)。
// while:先判条件,可能一次都不执行
var n = 3
while n > 0 {
print(n) // 3 2 1
n -= 1
}
// repeat-while:先执行一次再判(类似 do-while)
var password = ""
repeat {
password = generatePassword()
print("尝试: \(password)")
} while password != "8888"
// break:跳出整个循环
for i in 1...100 {
if i * i > 100 {
print("\(i) 时超过 100")
break
}
}
// continue:跳过本次,进入下次
for i in 1...10 {
if i % 2 == 0 { continue }
print(i) // 1 3 5 7 9
}
// 标签语句:跳出多层循环
outer: for i in 1...3 {
for j in 1...3 {
if i * j > 4 { break outer }
print("\(i)*\(j)=\(i*j)")
}
}6. break / continue / 标签
- break:跳出当前循环。
- continue:跳过本次,进入下次迭代。
- 标签:给循环起名字,跳出多层时用
break outer。 - fallthrough:在 switch 里强制贯穿下一个 case(极少用,知道即可)。
7. 控制流实战:猜数字
func generatePassword() -> String {
let n = Int.random(in: 1000...9999)
return String(n)
}把 guard、while、if-else 组合起来,就能写出可交互的小游戏。Swift 的语法让这种组合非常自然。
小结
Swift 的控制流"少而强":只有一个 for-in(没有 C 风格 for),guard 让代码扁平,switch 模式匹配无敌。下一篇讲函数——把控制流包装成可复用的代码块。
← 上一篇 Swift 运算符
下一篇 Swift 函数 →