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 的几个要点:

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:先判条件,可能一次都不执行
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 / 标签

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 函数

✈️💬