首页 / Swift 编程语言教程 / 控制转移

Swift 编程语言教程

控制转移

本教程共 93 篇 · 第 26 篇 · 更新于 2026-08-08 · 约 9 分钟阅读

SwiftSwift 编程语言教程breakcontinuefallthrough带标签语句控制转移嵌套循环

本节目标:用 break 跳出、用 continue 跳过本轮、用 fallthrough 主动贯穿,并在嵌套结构里用标签精准指定作用对象。

循环和 switch 默认都是“走完为止”。但现实里你常需要在中途做点特殊操作:某个条件满足就整个人退出循环,或者本轮不想要了直接进下一轮。Swift 用一组“控制转移语句”干这件事,它们能改变代码执行的默认顺序。

1-1 continue:本轮到此为止,下一轮继续

continue 的意思是“当前这轮我处理完了,跳到下一次迭代的开头”。它不会结束整个循环,只结束当前这一轮。

let puzzleInput = "great minds think alike"
var puzzleOutput = ""
let charactersToRemove: [Character] = ["a", "e", "i", "o", "u", " "]
for character in puzzleInput {
    if charactersToRemove.contains(character) {
        continue
    }
    puzzleOutput.append(character)
}
print(puzzleOutput)

这段代码想去掉所有元音和空格。遇到要删的字符就 continue,直接跳到下一个字符,不执行后面的 append。最终拼出 "grtmndsthnklk"

Tip

continue 理解为“这轮我不玩了,下一个谁来”。它特别适合“过滤掉不想要的元素”这类任务,把判断和跳过写在一行,主干逻辑不会被打断。

1-2 break:整个结构立刻结束

break 更彻底:它立刻终止所在的那个循环或 switch,后面的轮次和代码一概不跑。

在循环里,break 跳出整个循环,控制权交到循环后面的代码。在 switch 里,break 用来“匹配但故意什么都不做”(基础章节讲过)。

for number in 1...10 {
    if number == 5 {
        break
    }
    print(number)
}

打印 1、2、3、4,遇到 5 就 break,整个循环结束,永远不会到 6。注意它和 continue 的区别:continue 只是跳过本轮,循环还会继续;break 是连循环都不要了。

1-3 fallthrough:主动贯穿到下一个 case

Swift 的 switch 默认不贯穿(基础章节强调过)。但如果你想模拟 C 语言那种“一个 case 跑完接着跑下一个 case”的行为,可以显式写 fallthrough

let integerToDescribe = 5
var description = "数字 \(integerToDescribe) 是"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
    description += "一个质数,同时还是"
    fallthrough
default:
    description += "一个整数。"
}
print(description)

5 是质数,命中第一个 case,追加文字后用 fallthrough 主动掉进 default,再追加“一个整数。”。最终得到“数字 5 是一个质数,同时还是一个整数。”

Warning

fallthrough 不会重新检查下一个 case 的条件,它是无条件地、硬性地跳进下一个 case 的语句体。这和 C 的默认贯穿一致,用的时候心里要有数,别以为它会再匹配一次。绝大多数 Swift 代码根本不需要 fallthrough,只在刻意模拟贯穿行为时才用。

1-4 嵌套结构带来的歧义

当循环套循环、或循环里套 switch,breakcontinue 到底作用于哪一层,就成了问题。默认情况下,break 只结束最内层的那个结构。

for i in 1...3 {
    for j in 1...3 {
        if j == 2 {
            break
        }
        print("i=\(i), j=\(j)")
    }
}

这里的 break 只跳出内层 j 循环。外层 i 循环照常三轮,所以会打印 i=1, j=1i=2, j=1i=3, j=1。如果你本意是想让 j==2 时连外层一起停,这个写法就错了。这种歧义在嵌套深的时候特别容易误判。

1-5 带标签语句:指名道姓地控制

为解决上面的歧义,Swift 允许给循环或条件语句加一个标签(label)。标签写在关键字前面,后面跟冒号,然后才是结构本身。

gameLoop: while square != finalSquare {
    diceRoll += 1
    if diceRoll == 7 { diceRoll = 1 }
    switch square + diceRoll {
    case finalSquare:
        break gameLoop
    case let newSquare where newSquare > finalSquare:
        continue gameLoop
    default:
        square += diceRoll
        square += board[square]
    }
}

gameLoop: 是贴在 while 上的标签。break gameLoop 明确表示“跳出这个 while 循环”,而不是跳出里面的 switch;continue gameLoop 表示“直接进入 while 的下一轮”。标签让控制流向一目了然,不再有“到底作用于哪层”的猜测。

Note

标签不是必须用的。只有一层循环时,普通 break/continue 就够清楚。只有在嵌套结构里需要精确指定目标时,标签才显出价值。给标签起个有意义的名字(如 gameLoopouterLoop)比用 loop1 强得多,读代码的人一眼就懂。

1-6 另外两个控制转移语句

Swift 还有 returnthrow,它们也属于控制转移,但作用对象不同:return 结束整个函数并返回(下一模块讲函数时细说),throw 抛出错误提前退出(错误处理章节会讲)。本章聚焦在循环和 switch 内部常用的 breakcontinuefallthrough

1-7 continue 不能用于 switch

有一点要拎清:break 在循环和 switch 里都能用,但 continue 只能用在循环里。switch 没有“下一轮”的概念,所以在 switch 里写 continue 会编译报错。如果你在 switch 里想“跳过剩下的、去处理下一个数据”,那说明你大概率把 switch 放在了循环里——这时 continue 跳的是外层循环,不是 switch 本身。

1-8 使用建议

控制转移语句用得好能救命,用过头会让流程变得难追。几条经验:

第一,尽量让循环只有一个出口。满屏 break 的代码,读的人很难理清何时退出。能用条件自然结束,就别到处 break

第二,标签只在真正嵌套时才加。一层循环用 break 足够清楚,乱加标签反而显得你在怀疑自己。

第三,fallthrough 是稀有物。绝大多数 Swift 代码不需要它,遇到别人写的 fallthrough 多看一眼,确认他是真的想要贯穿行为。

记住一个核心区别:continue 是“跳过本轮”,break 是“结束整个”,fallthrough 是“硬闯下一个 case”。配合标签,你就能在任意复杂的嵌套里收放自如。下一章看 guard,它用另一种思路做“提前退出”。

1-9 控制转移与函数返回的关系

breakcontinuefallthrough 管的是“循环和 switch 内部”的流向,而函数层面还有个更彻底的退出方式:returnreturn 不管你嵌套了多少层循环,直接结束整个函数。所以当你在深层循环里发现“可以结束了,而且后面也不用做了”,与其层层 break,不如直接 return(如果语义允许)。

同理,throw 能抛出错误提前退出。这些“退出通道”级别不同:continue 最轻(只跳本轮),break 中等(结束当前结构),return/throw 最重(结束整个函数)。理解这个层级,你就能在合适的粒度上控制流程,不滥用也不欠缺。

控制转移语句本质上是在帮你对“流程”做精细手术。用得克制,代码读起来像顺流而下;用得泛滥,代码就会跳来跳去像断了线的珠子。一个朴素的标准是:如果不用 break/continue 也能把逻辑写清楚,那就不用。把判断写进循环条件本身,往往比在循环体里到处插 break 更清晰。工具在手,分寸在心。