作者刘文涛
转载请注明出处
控制流(Control Flow)
Swift 提供了多种流程控制结构,包括可以多次执行任务的 while
循环,基于特定条件选择执行不同代码分支的 if
,guard
和switch
语句,还有控制流程跳转到其他代码位置的break
和continue
语句。
Swift还提供了 for-in
循环,用来更简单地遍历数组,字典,区间(range),字符串和其他序列类型。
Swift 的switch
语句比C语言中更强大。在C语言中,如果某个case不小心漏写了break
,这个case就会贯穿至下一个case,Swift无需写break
,所以不会发生这种贯穿的情况。case 还可以匹配很多不同的模式,包括间隔匹配(interval match),元组(tuple)和转换到特定类型。 switch 语句的 case
中匹配的值可以绑定成临时常量或变量,在case体内使用,也可以用 where
来描述更复杂的匹配条件。
For-In 循环
你可以使用 for-in
循环来遍历一个集合中的所有元素,例如数字范围、数组中的元素或者字符串中的字符。
这个例子计算 base 这个数的 power 次幂。进行遍历的元素是使用闭区间操作符( … )表示的从 1 到 10 的数字区间。这个计算并不需要知道每一次循环中计数器具体的值,只需要执行了正确的次数即可。下划线符号 _
(替代循环中的变量)能够忽略当前值,并且不提供循环遍历时对值的访问。
While 循环
while 循环会一直运行一段语句知道条件变成 false 。这类循环适合使用在第一次迭代前,迭代次数未知的情况下。Swift提供两种 while 循环形式:
• while循环,每次在循环开始时计算条件是否符合;
• repeat-while循环,每次在循环结束时计算条件是否符合。
while
循环从计算一个条件开始。如果条件为true
,会重复运行一段语句,直到条件变为false
。while
循环的另外一种形式是repeat-while
,它和while
的区别是在判断循环条件之前,先执行一次循环的代码块。然后重复循环直到条件为false
。
Swift语言的 repeat-while 循环和其他语言中的 do-while 循环是类似的。
下面是 repeat-while
循环的一般格式:
条件语句
Swift提供两种类型的条件语句:if 语句和 switch 语句。通常,当条件较为简单且可能的情况很少时,使用 if 语句。而 switch 语句更适用于条件较复杂。有更多排列组合的时候。并且 switch 在需要用到模式匹配(pattern-matching)的情况下会更有用。
if
if 语句最简单的形式就是只包含一个条件,只有该条件为 true 时,才执行相关代码。当然,if 语句允许二选一执行,叫做else从句。也就是当条件为false时,执行else语句。
switch
switch语句会尝试把某个值与若干个模式进行匹配。根据第一个匹配成功的模式,switch语句会执行对应的代码。当有可能的情况较多时,通常用switch语句替换if语句。
|
|
switch 语句必须是完备的。这就是说,每一个可能的值都必须至少有一个 case 分支与之对应。在某些不可能涵盖所有值的情况下,你可以使用默认( default )分支来涵盖其它所有没有对应的值,这个默认分支必须在 switch 语句的最后面。
不存在隐式的贯通
与 C 和 Objective-C 中的 switch 语句不同,在 Swift 中,当匹配的 case 分支中的代码执行完毕后,程序会终止 switch 语句,而不会继续执行下一个 case 分支。这也就是说,不需要在 case 分支中显式地使用 break 语句。这使得 switch 语句更安全、更易用,也避免了因忘记写 break 语句而产生的错误。
每一个 case 分支都必须包含至少一条语句。
为了让单个case同时匹配 a 和 A ,可以将这个两个值组合成一个复合匹配,并且用逗号分开。
不像C语言,Swift允许多个case匹配同一个值。但是,如果存在多个匹配,那么只会执行第一个被匹配到的case分支。因此剩下的能够匹配的分支都会被忽视掉。
值绑定
case 分支允许将匹配的值绑定到一个临时的常量或变量,并且在case分支体内使用 – 这种行为被称为值绑定,因为匹配的值在case分支体内,与临时的常量或变量绑定。
下面的例子展示了如何在一个 (Int, Int) 类型的元组中使用值绑定来分类下图中的点(x, y):
|
|
请注意,这个 switch 语句不包含默认分支。这是因为最后一个 case —— case let(x, y) 声明了一个可以匹配余下所有值的元组。这使得 switch 语句已经完备了,因此不需要再书写默认分支。
where
case 分支的模式可以使用where语句来判断额外的条件。
下面的例子把下图中的点(x, y)进行了分类:
|
|
这三个 case 都声明了常量 x 和 y 的占位符,用于临时获取元组 yetAnotherPoint 的两个值。这两个常量被用作 where 语句的一部分,从而创建一个动态的过滤器(filter)。当且仅当 where 语句的条件为 true 时,匹配到的case 分支才会被执行。
就像是值绑定中的例子,由于最后一个 case 分支匹配了余下所有可能的值, switch 语句就已经完备了,因此不需要再书写默认分支。
控制转移语句
控制转移语句改变你代码的执行顺序,通过它可以实现代码的跳转。Swift 有五种控制转移语句:
• continue
• break
• fallthrough
• return
• throw
continue 语句告诉一个循环体立刻停止本次循环,重新开始下次循环。就好像在说“本次循环我已经执行完了”,但是不会离开整个循环体。
下面的例子把一个小写字符串中的元音字母和空格字符移除,生成一个含义模糊的短句:
|
|
在上面的代码中,只要匹配到元音字母或者空格字符,就调用continue语句,使本次循环结束,重新开始下次循环。
break 语句会立刻结束整个控制流的执行。
当在一个循环体中使用 break 时,会立刻中断循环体的执行,然后跳到表示循环体结束的大括号后的第一行代码。不会再有本次循环的代码在执行,也不会有下次的循环产生。
当在一个switch代码块中使用break时,会立即中断该switch代码块的执行,并且跳到表示switch代码块结束的大括号后的第一行代码。
这种特性可以被用来匹配或者忽略一个或多个分支。因为 Swift 的 switch 需要包含所有的分支而且不允许有为空的分支,有时为了使你的意图更明显,需要特意匹配或者忽略某个分支。那么当你想忽略某个分支时,可以在该分支内写上 break 语句。当那个分支被匹配到时,分支内的 break 语句立即结束 switch 代码块。
Swift中的switch不会从上一个case分支落入到下一个case分支中。相反,只要第一个匹配到的case分支完成了它需要执行的语句,整个switch代码块完成了它的执行。相比之下,C 语言要求你显式地插入 break 语句 到每个 case 分支的末尾来阻止自动落入到下一个 case 分支中。Swift 的这种避免默认落入到下一个分支中的特性意味着它的 switch 功能要比 C 语言的更加清晰和可预测,可以避免无意识地执行多个 case 分支从而引发的错误。
如果你确实需要C风格的贯穿特性,你可以再每个需要该特性的case分支中使用 fallthrough 关键字。
|
|
提前退出
像if语句一样,guard 的执行取决于一个表达式的布尔值。我们可以使用guard语句来要求条件必须为真时,以执行guard语句后的代码。不同于if语句,一个guard语句总是有一个else从句,如果条件不为真则执行else从句中的代码。
|
|
相比于可以实现同样功能的if语句,按需要使用guard语句会提升我们代码的可读性。它可以使你的代码连贯的被执行而不需要将它包在 else 块中,它可以使你在紧邻条件判断的地方,处理违规的情况。