Swift: Swift 循环:for-in、while 和 repeat-while
循环让计算机重复执行相同的任务,就像流水线机器不停运转。本课带你掌握 Swift 中所有循环方式的适用场景和最佳实践。
1. 你将学到
- 使用 for-in 遍历数组、区间和字典
- 使用 while 在条件满足时反复执行
- 使用 repeat-while 确保至少执行一次
- 使用 break 和 continue 控制循环流程
- 使用标签语句跳出多层嵌套循环
2. 一个数据分析师的真实故事
(1) 痛点:手工处理 10 万行日志,手指都要断了
Charlie 是一家电商平台的数据分析师。每天需要扫描 10 万行服务器日志,统计错误率、响应时间和异常模式。他最初手动一行行复制粘贴到 Excel 里操作: `swift // 模拟他的痛苦:手动逐条处理 let logEntry1 = "2026-07-15 10:23:45 [ERROR] DB timeout" let logEntry2 = "2026-07-15 10:24:01 [INFO] Request completed" // ...还有 99,998 行等着 Charlie 每天花 3 小时做这种重复劳动,还经常漏数。他需要一个自动化工具来遍历所有日志。
(2) for-in 循环的解法
`swift let logEntries = [ "2026-07-15 10:23:45 [ERROR] DB timeout", "2026-07-15 10:24:01 [INFO] Request completed", "2026-07-15 10:25:30 [ERROR] Connection refused" ] var errorCount = 0 for entry in logEntries { if entry.contains("[ERROR]") { errorCount += 1 } } print("Found (errorCount) errors in log")
(3) 收益:3 小时缩到 3 秒
| 维度 | 手工 Excel | 循环自动化 |
|---|---|---|
| 处理 10 万行耗时 | 3 小时 | 3 秒 |
| 漏数/错数 | 5-10 个 | 0 |
| 可重复使用 | 否 | 是(改个文件名就行) |
| Charlie 的心情 | 崩溃 | 愉快 |
3. for-in 循环
for-in 是 Swift 中使用频率最高的循环,用于遍历序列(数组、区间、字典等)。 `mermaid graph LR A[Sequence] --> B[Next Element] B --> C[Execute Body] C --> D{More Elements?} D -->|Yes| B D -->|No| E[Continue]
| 遍历对象 | 语法 | 每次拿到的值 |
|---|---|---|
| 数组 | or item in array | 元素 |
| 区间 | or i in 1...5 | 索引值 |
| 字典 | or (key, val) in dict | 键值对元组 |
| 字符串 | or char in string | 字符 |
| 带索引数组 | or (i, item) in array.enumerated() | (索引, 元素) 元组 |
(1) 遍历数组和区间
`swift // 遍历数组 let fruits = ["apple", "banana", "orange"] for fruit in fruits { print("I like (fruit)") } // 遍历区间 for number in 1...5 { print("Count: (number)") } // 带索引遍历 let colors = ["red", "green", "blue"] for (index, color) in colors.enumerated() { print("(index + 1). (color)") }
(2) 遍历字典
`swift let scores = ["Alice": 95, "Bob": 82, "Charlie": 78] for (name, score) in scores { print("(name): (score)") }
▶ 示例:计算月平均气温
`swift // ============================================ // 用 for-in 遍历气温数据计算平均值 // ============================================ let monthlyTemps = [5.2, 8.1, 12.5, 18.3, 24.1, 30.2, 32.0, 31.5, 27.8, 21.3, 14.2, 8.9] var total = 0.0 for temp in monthlyTemps { total += temp } let average = total / Double(monthlyTemps.count) print("Total: (total) C") print("Average: (String(format: "%.1f", average)) C")
输出:
ext Total: 234.1 C Average: 19.5 C
4. while 和 repeat-while
while 在条件为 true 时重复执行,适合不知道具体循环次数的场景。repeat-while 至少执行一次。 `mermaid graph TB subgraph "while" A[Check Condition] -->|true| B[Execute Body] B --> A A -->|false| C[Exit] end subgraph "repeat-while" D[Execute Body] --> E[Check Condition] E -->|true| D E -->|false| F[Exit] end
| 类型 | 判断时机 | 最少执行次数 | 适用场景 |
|---|---|---|---|
| while | 执行前判断 | 0 次 | 条件驱动,可能一次都不执行 |
| epeat-while | 执行后判断 | 1 次 | 至少执行一次,如用户输入验证 |
(1) while 循环
`swift var countdown = 5 while countdown > 0 { print("(countdown)...") countdown -= 1 } print("Liftoff!")
(2) repeat-while 循环
`swift var attempts = 0 var success = false repeat { attempts += 1 print("Attempt #(attempts)...") success = Int.random(in: 1...10) > 5 } while !success && attempts < 3 print(success ? "Succeeded!" : "Failed after 3 attempts")
▶ 示例:猜数字游戏
`swift // ============================================ // 用 repeat-while 实现猜数字游戏 // ============================================ import Foundation let target = Int.random(in: 1...20) var guess = 0 var attempts = 0 print("Guess a number between 1 and 20") repeat { attempts += 1 guess = Int.random(in: 1...20) print("Attempt (attempts): guessed (guess)") if guess < target { print(" Too low") } else if guess > target { print(" Too high") } else { print(" Correct!") } } while guess != target print("Solved in (attempts) attempts!")
输出:
ext Guess a number between 1 and 20 Attempt 1: guessed 7 Too low Attempt 2: guessed 15 Too high Attempt 3: guessed 12 Correct! Solved in 3 attempts!
5. break、continue 和标签语句
break 立即退出循环,continue 跳过当前迭代进入下一轮。标签语句用于跳出多层嵌套循环。
| 指令 | 作用 | 使用场景 |
|---|---|---|
| reak | 立即终止当前循环 | 找到目标后提前退出 |
| continue | 跳过当前迭代,进入下一轮 | 过滤掉不符合条件的元素 |
reak <label> |
跳出指定标签的循环 | 跳出多层嵌套循环 |
continue <label> |
跳到指定标签循环的下一轮 | 多层循环的控制流 |
(1) break 和 continue
`swift let numbers = [3, 7, 1, 9, 4, 6, 8] // break: 找到第一个偶数就退出 for num in numbers { if num.isMultiple(of: 2) { print("Found first even: (num)") break } } // continue: 只打印奇数 for num in numbers { if num.isMultiple(of: 2) { continue } print("Odd: (num)") }
(2) 标签语句
`swift // 标签语句跳出多层循环 outerLoop: for i in 1...5 { for j in 1...5 { let product = i * j if product == 12 { print("Found: (i) x (j) = (product)") break outerLoop } } }
▶ 示例:日志过滤与分析
`swift // ============================================ // 用 break/continue 处理日志数据 // ============================================ let logEntries = [ "INFO Server started", "ERROR Database connection failed", "DEBUG Cache hit ratio 85%", "ERROR Timeout after 30s", "INFO Request completed in 120ms", "ERROR Disk space low" ] var errorCount = 0 for entry in logEntries { if entry.hasPrefix("DEBUG") { continue } if entry.hasPrefix("ERROR") { errorCount += 1 print("[ERROR #(errorCount)] (entry)") } if errorCount >= 5 { print("ALERT: Too many errors!") break } } print("Processed (logEntries.count) entries, found (errorCount) errors")
输出:
ext [ERROR #1] ERROR Database connection failed [ERROR #2] ERROR Timeout after 30s [ERROR #3] ERROR Disk space low Processed 6 entries, found 3 errors
6. 完整示例:批量日志统计分析工具
`swift // ============================================ // 日志分析工具 // 综合运用 for-in / while / break / continue // ============================================ import Foundation let logs = [ "[INFO] 2026-07-15 08:00:00 Server started", "[ERROR] 2026-07-15 08:05:23 DB connection timeout", "[INFO] 2026-07-15 08:10:45 Cache warmed up", "[ERROR] 2026-07-15 08:15:30 Disk I/O error", "[WARN] 2026-07-15 08:20:00 Memory usage 85%", "[ERROR] 2026-07-15 08:25:10 Request failed: timeout", "[INFO] 2026-07-15 08:30:00 Health check OK", "[DEBUG] 2026-07-15 08:35:00 Query plan: index scan", "[ERROR] 2026-07-15 08:40:00 Connection pool exhausted" ] var stats = (info: 0, warn: 0, error: 0, debug: 0) var errorLines: [String] = [] for entry in logs { if entry.hasPrefix("[DEBUG]") { stats.debug += 1 continue } if entry.hasPrefix("[ERROR]") { stats.error += 1 errorLines.append(entry) } else if entry.hasPrefix("[WARN]") { stats.warn += 1 } else if entry.hasPrefix("[INFO]") { stats.info += 1 } } print("=== Log Analysis Report ===") print("Total entries: (logs.count)") print("INFO: (stats.info) | WARN: (stats.warn) | ERROR: (stats.error) | DEBUG: (stats.debug)") if stats.error > 0 { print("\n=== Error Details ===") var i = 0 while i < errorLines.count { print("(i + 1). (errorLines[i])") i += 1 } print("\nError rate: (Double(stats.error) / Double(logs.count) * 100)%") }
输出: ` ext === Log Analysis Report === Total entries: 9 INFO: 3 | WARN: 1 | ERROR: 4 | DEBUG: 1
=== Error Details ===
- [ERROR] 2026-07-15 08:05:23 DB connection timeout
- [ERROR] 2026-07-15 08:15:30 Disk I/O error
- [ERROR] 2026-07-15 08:25:10 Request failed: timeout
- [ERROR] 2026-07-15 08:40:00 Connection pool exhausted
Error rate: 44.4% `
❓ 常见问题
📖 小节
- for-in 是 Swift 最常用的循环,用于遍历数组、区间、字典等序列
- while 适合条件驱动的循环,可能执行 0 次
- repeat-while 确保循环体至少执行 1 次
- break 立即终止当前循环,continue 跳过本轮剩余代码
- 标签语句可以跳出或跳过多层嵌套循环
- enumerated() 可以在 for-in 中同时获取索引和元素
📝 作业
- 基础题: 用 for-in 遍历 1 到 10 的区间,打印每个数的平方(例如 "2 的平方是 4")。
- 进阶题: 用 while 实现一个简单计数器:从 100 开始每次减 7,打印每一步的值,直到小于 0 为止。
- 挑战题: 写一个嵌套循环程序,生成 9x9 乘法表。要求使用标签语句和 break/continue 来控制输出格式(例如,跳过 5 的倍数的行)。