Swift: Swift 循环:for-in、while 和 repeat-while

循环让计算机重复执行相同的任务,就像流水线机器不停运转。本课带你掌握 Swift 中所有循环方式的适用场景和最佳实践。

1. 你将学到


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 ===

  1. [ERROR] 2026-07-15 08:05:23 DB connection timeout
  2. [ERROR] 2026-07-15 08:15:30 Disk I/O error
  3. [ERROR] 2026-07-15 08:25:10 Request failed: timeout
  4. [ERROR] 2026-07-15 08:40:00 Connection pool exhausted

Error rate: 44.4% `


❓ 常见问题

Q for-in 和 while 应该怎么选择?
A 知道要遍历什么用 for-in(如数组、区间)。不知道循环次数、需要条件驱动用 while。至少执行一次用 repeat-while。
Q enumerated() 返回的 index 从 0 开始还是从 1 开始?
A 从 0 开始。如果你想要从 1 开始显示,在打印时加 1 即可。
Q while 和 repeat-while 的区别到底是什么?
A while 在执行循环体前检查条件,可能一次都不执行。repeat-while 先执行循环体再检查条件,至少执行一次。
Q break 和 continue 有什么区别?
A break 终止整个循环,continue 跳过当前迭代进入下一轮。打比方:break 是直接退出电影院,continue 是跳过不好看的片段继续看。
Q 标签语句中的标签名称有什么限制?
A 标签名是自定义标识符,通常用有意义的名称如 outerLoop、 owLoop,后面跟冒号,放在 or 或 while 前面。

📖 小节


📝 作业

  1. 基础题: 用 for-in 遍历 1 到 10 的区间,打印每个数的平方(例如 "2 的平方是 4")。
  2. 进阶题: 用 while 实现一个简单计数器:从 100 开始每次减 7,打印每一步的值,直到小于 0 为止。
  3. 挑战题: 写一个嵌套循环程序,生成 9x9 乘法表。要求使用标签语句和 break/continue 来控制输出格式(例如,跳过 5 的倍数的行)。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏