Swift for-in 循环(完整教程)

Swift for-in 循环:从入门到精通

在 Swift 编程语言中,循环结构是处理重复任务的核心工具。其中,for-in 循环以其简洁、安全和易读的特性,成为开发者日常使用频率最高的循环方式之一。无论是遍历数组、字典,还是处理集合数据,for-in 循环都能以极低的学习成本完成高效操作。

如果你刚接触 Swift,或者正在从其他语言(如 Java 8、Python)迁移到 Swift,那么掌握 for-in 循环将是你迈出坚实一步的关键。它不像传统的 for 循环那样需要手动管理索引,而是“自动感知”集合的每一个元素,让你更专注于业务逻辑本身。

接下来,我们就从基础语法开始,一步步拆解 for-in 循环的使用场景与底层原理。


基础语法与工作原理

for-in 循环的核心语法结构非常简单:

for 变量 in 集合 {
    // 循环体:每次迭代执行的代码
}

这里的 变量 会自动从集合中取出一个元素,并在每次迭代中赋值。整个过程由 Swift 编译器自动管理,无需手动控制索引或边界。

我们来看一个最基础的例子:

let fruits = ["苹果", "香蕉", "橙子", "葡萄"]

for fruit in fruits {
    print("今天吃 \(fruit)")
}

注释

  • fruits 是一个字符串数组,包含四种水果。
  • for fruit in fruits 表示“对 fruits 中的每一个 fruit 执行一次循环体”。
  • print("今天吃 \(fruit)") 会依次输出每种水果的名称。
  • Swift 会自动迭代集合中的每个元素,无需手动写 i < fruits.count 这类条件。

这个结构就像一个“自动分拣流水线”:你只需告诉它“要处理哪些东西”,它就会一个一个地帮你处理完毕,全程无需你操心“第几个”“什么时候停”。


遍历数组:最常见场景

数组是 for-in 循环最常见的应用对象。它能安全地遍历所有元素,且不会越界。

创建数组与初始化

let scores = [88, 92, 76, 95, 83]

for score in scores {
    if score >= 90 {
        print("优秀!分数是 \(score)")
    } else {
        print("还需努力,分数是 \(score)")
    }
}

注释

  • scores 是一个整数数组,存储了五位同学的考试成绩。
  • for score in scores 会依次取出每个分数。
  • 在循环体内,我们根据分数判断是否“优秀”,并输出相应提示。
  • 因为 Swift 会自动管理迭代过程,所以完全不用担心数组越界问题。

这个例子展示了 for-in 如何让逻辑更清晰——你不再需要关心“i 是多少”,而是直接关注“当前这个元素是什么”。


遍历字典:键值对的优雅处理

字典(Dictionary)是键值对的集合,for-in 循环同样可以轻松遍历它。关键在于,你需要明确如何解包键和值。

单独获取键或值

let studentGrades = [
    "张三": 88,
    "李四": 95,
    "王五": 76,
    "赵六": 92
]

// 只遍历键(名字)
for name in studentGrades.keys {
    print("学生:\(name)")
}

// 只遍历值(分数)
for grade in studentGrades.values {
    print("成绩:\(grade)")
}

注释

  • studentGrades.keys 返回所有键(学生姓名)的集合。
  • studentGrades.values 返回所有值(成绩)的集合。
  • 你可以选择性地只遍历其中一部分,这在数据筛选时非常有用。

同时获取键和值

for (name, grade) in studentGrades {
    print("\(name) 的成绩是 \(grade)")
}

注释

  • (name, grade) 是一个元组解构语法,Swift 会自动将字典的每个键值对拆解为两个变量。
  • 这种写法简洁且高效,是遍历字典的标准做法。
  • 就像拆快递:你拿到一个包裹,拆开后得到“名字”和“成绩”两个内容。

遍历范围:处理数字序列

for-in 循环不仅可以遍历集合,还能处理数字范围。这在需要执行固定次数操作时特别实用。

使用闭区间(...)

for i in 1...5 {
    print("第 \(i) 次循环")
}

注释

  • 1...5 表示从 1 到 5(包含 5)的闭区间。
  • 循环会执行 5 次,i 的值依次为 1、2、3、4、5。
  • 这种方式等价于传统 for (int i = 1; i <= 5; i++),但更安全、更直观。

使用半开区间(..<)

for j in 0..<3 {
    print("索引:\(j) 处理数据")
}

注释

  • 0..<3 表示从 0 到 3(不包含 3)的半开区间。
  • 所以 j 的值是 0、1、2,共三次。
  • 这在数组遍历中非常常见,比如 for i in 0..<array.count,避免越界。

小贴士
如果你用 ... 遍历数组索引,一定要小心 array.count 是否正确,避免访问 array[array.count] 这类越界错误。而 ..< 天然避免了这个问题,是更推荐的方式。


处理复杂场景:嵌套与提前退出

for-in 循环支持嵌套结构,也能与 breakcontinue 配合使用,实现更复杂的控制流程。

嵌套循环:遍历二维数组

let matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

for row in matrix {
    for element in row {
        print(element, terminator: " ") // 不换行
    }
    print() // 换行
}

注释

  • matrix 是一个二维数组,表示一个 3x3 的数字矩阵。
  • 外层循环遍历每一行(row),内层循环遍历行内的每一个元素。
  • terminator: " " 防止每打印一个数字就换行,保持在同一行。
  • print() 用于换行,确保每行数据独立显示。

这种嵌套结构就像“翻一页书”,先看第一页,再逐行看内容,逻辑清晰。

提前退出与跳过

let numbers = [10, 25, 30, 45, 50, 60]

for num in numbers {
    if num % 2 != 0 {
        continue // 跳过奇数
    }
    if num > 55 {
        break // 大于 55 就停止
    }
    print("偶数且小于 55:\(num)")
}

注释

  • continue 用于跳过当前迭代,继续下一次循环。
  • break 用于完全退出循环,不再执行后续内容。
  • 这里只打印出 103045,因为 50 虽然偶数,但 >55 时触发 break

这就像在超市挑选商品:你只想要价格小于 55 的偶数商品,遇到奇数就跳过,遇到太贵的就直接离开。


性能与最佳实践建议

虽然 for-in 循环简洁易用,但在实际项目中仍需注意几点:

  • 避免在循环中修改原集合:如果在 for-in 中修改数组或字典,可能导致未定义行为或崩溃。
    例如:for item in array { array.remove(at: 0) } 是危险的。

  • 使用 stride 实现非连续遍历

// 从 0 到 10,步长为 2
for i in stride(from: 0, through: 10, by: 2) {
    print(i)
}

注释

  • stride 允许你自定义起始值、终止值和步长。
  • 适用于每隔几个元素处理一次的场景。
  • 避免在循环中进行大量计算:如果循环体中包含复杂逻辑,考虑是否可以提前优化。

总结:为什么 for-in 循环如此重要?

Swift for-in 循环 是 Swift 语言设计哲学的缩影:安全、简洁、表达力强。它让你不再陷入索引管理的繁琐中,而是专注于“我需要处理什么”。

无论你是初学者还是中级开发者,只要你在处理集合数据,for-in 循环就是你最可靠的伙伴。它不仅语法简单,而且运行时安全,能有效防止越界错误,是 Swift 编程中不可或缺的工具。

掌握它,意味着你真正迈入了 Swift 的“优雅编程”世界。从今天开始,让每一个循环都清晰、安全、高效。