在 Swift 中,你可以在循环体和条件语句
中嵌套循环体和条件语句来创造复杂的控制流结构
。并且,循环体和条件语句都可以使用 break
语句来提前结束整个代码块。
因此,显式地指明 break 语句想要终止的是哪个循环体或者条件语句,会很有用。类似地,如果你有许多嵌套的循环体,显式指明 continue 语句想要影响哪一个循环体也会非常有用。
为了实现这个目的,你可以使用标签(statement label)
来标记一个循环体或者条件语句,对于一个条件语句,你可以使用 break 加标签
的方式,来结束这个被标记的语句。
对于一个循环语句,你可以使用 break 或者 continue 加标签
,来结束或者继续这条被标记语句的执行。
声明一个带标签的语句是通过在该语句的关键词的同一行前面放置一个标签,作为这个语句的前导关键字(introducer keyword),并且该标签后面跟随一个冒号。
下面是一个针对 while 循环体的标签语法,同样的规则适用于所有的循环体和条件语句。
label name: while condition {
statements
}
下面的例子是前面章节中蛇和梯子的适配版本,在此版本中,我们将使用一个带有标签的 while 循环体中调用 break 和 continue 语句。
这次,游戏增加了一条额外的规则:
- 为了获胜,你必须刚好落在第 25 个方块中。
如果某次掷骰子使你的移动超出第 25 个方块,你必须重新掷骰子,直到你掷出的骰子数刚好使你能落在第 25 个方块中。
游戏的棋盘和之前一样:

// 初始化 finalSquare、board、square 和 diceRoll
let finalSquare = 25
var board = [Int](repeating: 0, count: finalSquare + 1)
board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
var square = 0
var diceRoll = 0
这个版本的游戏使用 while 循环和 switch 分支语句
来实现游戏的逻辑。
while 循环有一个标签名 gameLoop
,来表明它是游戏的主循环。
该 while 循环体的条件判断语句是while square !=finalSquare
,这表明你必须刚好落在方格25中。
// while 循环体
gameLoop: while square != finalSquare {
diceRoll += 1
if diceRoll == 7 { diceRoll = 1 }
// switch控制语句
switch square + diceRoll {
case finalSquare:
// 骰子数刚好使玩家移动到最终的方格里,游戏结束。
break gameLoop
case let newSquare where newSquare > finalSquare:
// 骰子数将会使玩家的移动超出最后的方格,那么这种移动是不合法的,玩家需要重新掷骰子
continue gameLoop
default:
// 合法移动,做正常的处理
square += diceRoll
square += board[square]
}
}
print("Game over!")
每次循环迭代开始时掷骰子。与之前玩家掷完骰子就立即移动不同,这里使用了 switch 语句来考虑每次移动可能产生的结果,从而决定玩家本次是否能够移动。
-
如果骰子数刚好使玩家移动到最终的方格里,游戏结束。
break gameLoop
语句跳转控制去执行while 循环体
后的第一行代码打印 Game Over,意味着游戏结束。 -
如果骰子数将会使玩家的移动超出最后的方格,那么这种移动是不合法的,玩家需要重新掷骰子。
continue gameLoop
语句结束本次 while 循环,开始下一次循环。 -
在剩余的所有情况中,骰子数产生的都是合法的移动。玩家向前移动 diceRoll 个方格,然后游戏逻辑再处理玩家当前是否处于蛇头或者梯子的底部。接着本次循环结束,控制跳转到 while 循环体的条件判断语句处,再决定是否需要继续执行下次循环。
⚠️注意
如果上述的
break 语句
没有使用gameLoop
标签,那么它将会中断 switch 语句而不是 while 循环。
使用 gameLoop 标签清晰的表明了 break 想要中断的是哪个代码块。
同时请注意,当调用continue gameLoop
去跳转到下一次循环迭代时,这里使用 gameLoop 标签并不是严格必须的。
因为在这个游戏中,只有一个循环体,所以 continue 语句会影响到哪个循环体是没有歧义的。然而,continue 语句使用 gameLoop 标签也是没有危害的。这样做符合标签的使用规则,同时参照旁边的 break gameLoop,能够使游戏的逻辑更加清晰和易于理解。
网友评论