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: 0
Count is: 1
Count 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: 0
Count is: 1
Count is: 2
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count 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 = 1
var x = 4
switch 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 = 1
var x = 4
switch x {
case 1:
j++
case 2:
j++
case 3:
j++
case 4:
j++
fallthrough
case 5:
j++
fallthrough
default:
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
分支而设的。或许这种语句我们用得很少,但作为一门编程语言,还是要照顾用户的少数特殊需求。