7.3 跳转语句

跳转语句能够改变程序的执行顺序,可以实现程序的跳转。Swift有4种跳转语句:breakcontinuefallthroughreturn。其中return语句与函数返回有关,我们将在第9章介绍return,本章重点介绍breakcontinuefallthrough语句的使用。

7.3.1 break语句

break语句可用于上一节介绍的whiledo whileforfor in循环结构,它的作用是强行退出循环结构,不执行循环结构中剩余的语句。

提示 break语句也可用于switch分支语句,但switch默认在每一个分支之后隐式地添加了break,我们一定要显式地添加break才可以使程序运行不受影响。

在循环体中使用break语句有两种方式:可以带有标签,也可以不带标签。语法格式如下:

  1. break //不带标签
  2. break label //带标签,label是标签名

定义标签的时候后面跟一个冒号。不带标签的break语句使程序跳出所在层的循环体,而带标签的break语句使程序跳出标签指示的循环体。

下面看一个示例,代码如下:

  1. let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  2. for var i = 0; i < countElements(numbers); i++
  3. {
  4. if i == 3 {
  5. break
  6. }
  7. println("Count is: \(i)")
  8. }

在上述程序代码中,当条件i==3的时候执行break语句,break语句会终止循环,程序运行的结果如下:

  1. Count is: 0
  2. Count is: 1
  3. Count is: 2

break还可以配合标签使用,示例代码如下:

  1. label1: for var x = 0; x < 5; x++ {
  2. label2: for var y = 5; y > 0; y-- {
  3. if y == x {
  4. break label1
  5. }
  6. println("(x,y) = (\(x),\(y))")
  7. }
  8. }
  9. println("Game Over!")

默认情况下,break只会跳出最近的内循环(代码第②行for循环)。如果要跳出代码第①行的外循环,可以为外循环添加一个标签label1:,然后在第③行的break语句后面指定这个标签label1,这样当条件满足执行break语句的时候,程序就会跳转出外循环了。

程序运行结果如下:

  1. (x,y) = (0,5)
  2. (x,y) = (0,4)
  3. (x,y) = (0,3)
  4. (x,y) = (0,2)
  5. (x,y) = (0,1)
  6. (x,y) = (1,5)
  7. (x,y) = (1,4)
  8. (x,y) = (1,3)
  9. (x,y) = (1,2)
  10. Game Over!

如果break后面没有指定外循环标签,则运行结果如下:

  1. (x,y) = (0,5)
  2. (x,y) = (0,4)
  3. (x,y) = (0,3)
  4. (x,y) = (0,2)
  5. (x,y) = (0,1)
  6. (x,y) = (1,5)
  7. (x,y) = (1,4)
  8. (x,y) = (1,3)
  9. (x,y) = (1,2)
  10. (x,y) = (2,5)
  11. (x,y) = (2,4)
  12. (x,y) = (2,3)
  13. (x,y) = (3,5)
  14. (x,y) = (3,4)
  15. (x,y) = (4,5)
  16. Game Over!

比较两种运行结果,就会发现给break添加标签的意义,添加标签对于多层嵌套循环是很有必要的,适当使用可以提高程序的执行效率。

7.3.2 continue语句

continue语句用来结束本次循环,跳过循环体中尚未执行的语句,接着进行终止条件的判断,以决定是否继续循环。对于for语句,在进行终止条件的判断前,还要先执行迭代语句。

在循环体中使用continue语句有两种方式可以带有标签,也可以不带标签。语法格式如下:

  1. continue //不带标签
  2. continue label //带标签,label是标签名

下面看一个示例,代码如下:

  1. let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  2. for var i = 0; i < countElements(numbers); i++
  3. {
  4. if i == 3 {
  5. continue
  6. }
  7. println("Count is: \(i)")
  8. }

在上述程序代码中,当条件i==3的时候执行continue语句,continue语句会终止本次循环,循环体中continue之后的语句将不再执行,接着进行下次循环,所以输出结果中没有3。程序运行结果如下:

  1. Count is: 0
  2. Count is: 1
  3. Count is: 2
  4. Count is: 4
  5. Count is: 5
  6. Count is: 6
  7. Count is: 7
  8. Count is: 8
  9. Count is: 9

带标签的continue语句示例代码如下:

  1. label1: for var x = 0; x < 5; x++ {
  2. label2: for var y = 5; y > 0; y-- {
  3. if y == x {
  4. continue label1
  5. }
  6. println("(x,y) = (\(x),\(y))")
  7. }
  8. }
  9. println("Game Over!")

默认情况下,continue只会跳出最近的内循环(代码第②行for循环),如果要跳出代码第①行的外循环,可以为外循环添加一个标签label1:,然后在第③行的continue语句后面指定这个标签label1,这样当条件满足执行continue语句时候,程序就会跳转出外循环了。

程序运行结果如下:

  1. (x,y) = (0,5)
  2. (x,y) = (0,4)
  3. (x,y) = (0,3)
  4. (x,y) = (0,2)
  5. (x,y) = (0,1)
  6. (x,y) = (1,5)
  7. (x,y) = (1,4)
  8. (x,y) = (1,3)
  9. (x,y) = (1,2)
  10. (x,y) = (2,5)
  11. (x,y) = (2,4)
  12. (x,y) = (2,3)
  13. (x,y) = (3,5)
  14. (x,y) = (3,4)
  15. (x,y) = (4,5)
  16. Game Over!

由于跳过了x==y,因此下面的内容没有输出。

  1. (x,y) = (1,1)
  2. (x,y) = (2,2)
  3. (x,y) = (3,3)
  4. (x,y) = (4,4)

7.3.3 fallthrough语句

fallthrough是贯通语句,只能使用在switch语句中。为了防止错误的发生,Swift中的switch语句case分支默认不能贯通,即执行完一个case分支就跳出switch语句。但是凡事都有例外,如果你的算法真的需要多个case分支贯通,也可以使用fallthrough语句。

下面是一个没有贯通的示例代码:

  1. var j = 1
  2. var x = 4
  3. switch x {
  4. case 1:
  5. j++
  6. case 2:
  7. j++
  8. case 3:
  9. j++
  10. case 4:
  11. j++
  12. case 5:
  13. j++
  14. default:
  15. j++
  16. }
  17. println("j = \(j)")

运行结果如下:

  1. j = 2

程序流程如图7-2所示,x = 4进入case 4,然后j++,跳出switch语句,所以最后输出j的值为2。

{%}

图 7-2 没有贯通的switch语句

我们来修改这个示例代码如下:

  1. var j = 1
  2. var x = 4
  3. switch x {
  4. case 1:
  5. j++
  6. case 2:
  7. j++
  8. case 3:
  9. j++
  10. case 4:
  11. j++
  12. fallthrough
  13. case 5:
  14. j++
  15. fallthrough
  16. default:
  17. j++
  18. }
  19. println("j = \(j)")

运行结果如下:

  1. j = 4

程序流程如图7-3所示,x = 4进入case 4分支,然后j++。由于fallthrough,程序会进入case 5分支,然后j++。由于还有fallthrough,程序会进入default分支,走完该分支后跳出switch语句,所以最后输出j的值为4。

{%}

图 7-3 有贯通的switch语句

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