7.3 跳转语句
跳转语句能够改变程序的执行顺序,可以实现程序的跳转。Swift有4种跳转语句:break、continue、fallthrough和return。其中return语句与函数返回有关,我们将在第9章介绍return,本章重点介绍break、continue和fallthrough语句的使用。
7.3.1 break语句
break语句可用于上一节介绍的while、do while、for和for in循环结构,它的作用是强行退出循环结构,不执行循环结构中剩余的语句。
提示
break语句也可用于switch分支语句,但switch默认在每一个分支之后隐式地添加了break,我们一定要显式地添加break才可以使程序运行不受影响。
在循环体中使用break语句有两种方式:可以带有标签,也可以不带标签。语法格式如下:
break //不带标签break label //带标签,label是标签名
定义标签的时候后面跟一个冒号。不带标签的break语句使程序跳出所在层的循环体,而带标签的break语句使程序跳出标签指示的循环体。
下面看一个示例,代码如下:
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]for var i = 0; i < countElements(numbers); i++{if i == 3 {break}println("Count is: \(i)")}
在上述程序代码中,当条件i==3的时候执行break语句,break语句会终止循环,程序运行的结果如下:
Count is: 0Count is: 1Count is: 2
break还可以配合标签使用,示例代码如下:
label1: for var x = 0; x < 5; x++ { ①label2: for var y = 5; y > 0; y-- { ②if y == x {break label1 ③}println("(x,y) = (\(x),\(y))")}}println("Game Over!")
默认情况下,break只会跳出最近的内循环(代码第②行for循环)。如果要跳出代码第①行的外循环,可以为外循环添加一个标签label1:,然后在第③行的break语句后面指定这个标签label1,这样当条件满足执行break语句的时候,程序就会跳转出外循环了。
程序运行结果如下:
(x,y) = (0,5)(x,y) = (0,4)(x,y) = (0,3)(x,y) = (0,2)(x,y) = (0,1)(x,y) = (1,5)(x,y) = (1,4)(x,y) = (1,3)(x,y) = (1,2)Game Over!
如果break后面没有指定外循环标签,则运行结果如下:
(x,y) = (0,5)(x,y) = (0,4)(x,y) = (0,3)(x,y) = (0,2)(x,y) = (0,1)(x,y) = (1,5)(x,y) = (1,4)(x,y) = (1,3)(x,y) = (1,2)(x,y) = (2,5)(x,y) = (2,4)(x,y) = (2,3)(x,y) = (3,5)(x,y) = (3,4)(x,y) = (4,5)Game Over!
比较两种运行结果,就会发现给break添加标签的意义,添加标签对于多层嵌套循环是很有必要的,适当使用可以提高程序的执行效率。
7.3.2 continue语句
continue语句用来结束本次循环,跳过循环体中尚未执行的语句,接着进行终止条件的判断,以决定是否继续循环。对于for语句,在进行终止条件的判断前,还要先执行迭代语句。
在循环体中使用continue语句有两种方式可以带有标签,也可以不带标签。语法格式如下:
continue //不带标签continue label //带标签,label是标签名
下面看一个示例,代码如下:
let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]for var i = 0; i < countElements(numbers); i++{if i == 3 {continue}println("Count is: \(i)")}
在上述程序代码中,当条件i==3的时候执行continue语句,continue语句会终止本次循环,循环体中continue之后的语句将不再执行,接着进行下次循环,所以输出结果中没有3。程序运行结果如下:
Count is: 0Count is: 1Count is: 2Count is: 4Count is: 5Count is: 6Count is: 7Count is: 8Count is: 9
带标签的continue语句示例代码如下:
label1: for var x = 0; x < 5; x++ { ①label2: for var y = 5; y > 0; y-- { ②if y == x {continue label1 ③}println("(x,y) = (\(x),\(y))")}}println("Game Over!")
默认情况下,continue只会跳出最近的内循环(代码第②行for循环),如果要跳出代码第①行的外循环,可以为外循环添加一个标签label1:,然后在第③行的continue语句后面指定这个标签label1,这样当条件满足执行continue语句时候,程序就会跳转出外循环了。
程序运行结果如下:
(x,y) = (0,5)(x,y) = (0,4)(x,y) = (0,3)(x,y) = (0,2)(x,y) = (0,1)(x,y) = (1,5)(x,y) = (1,4)(x,y) = (1,3)(x,y) = (1,2)(x,y) = (2,5)(x,y) = (2,4)(x,y) = (2,3)(x,y) = (3,5)(x,y) = (3,4)(x,y) = (4,5)Game Over!
由于跳过了x==y,因此下面的内容没有输出。
(x,y) = (1,1)(x,y) = (2,2)(x,y) = (3,3)(x,y) = (4,4)
7.3.3 fallthrough语句
fallthrough是贯通语句,只能使用在switch语句中。为了防止错误的发生,Swift中的switch语句case分支默认不能贯通,即执行完一个case分支就跳出switch语句。但是凡事都有例外,如果你的算法真的需要多个case分支贯通,也可以使用fallthrough语句。
下面是一个没有贯通的示例代码:
var j = 1var x = 4switch x {case 1:j++case 2:j++case 3:j++case 4:j++case 5:j++default:j++}println("j = \(j)")
运行结果如下:
j = 2
程序流程如图7-2所示,x = 4进入case 4,然后j++,跳出switch语句,所以最后输出j的值为2。

图 7-2 没有贯通的switch语句
我们来修改这个示例代码如下:
var j = 1var x = 4switch x {case 1:j++case 2:j++case 3:j++case 4:j++fallthroughcase 5:j++fallthroughdefault:j++}println("j = \(j)")
运行结果如下:
j = 4
程序流程如图7-3所示,x = 4进入case 4分支,然后j++。由于fallthrough,程序会进入case 5分支,然后j++。由于还有fallthrough,程序会进入default分支,走完该分支后跳出switch语句,所以最后输出j的值为4。

图 7-3 有贯通的switch语句
从以上两个例子可见,fallthrough就是为了贯穿case分支而设的。或许这种语句我们用得很少,但作为一门编程语言,还是要照顾用户的少数特殊需求。
