Swift5.1—控制转移语句

简介: Swift5.1—控制转移语句

控制转移语句改变你代码的执行顺序,通过它可以实现代码的跳转。


Continue



continue 语句告诉一个循环体立刻停止本次循环,重新开始下次循环。就好像在说“本次循环我已经执行完了”,但是并不会离开整个循环体。

下面的例子把一个小写字符串中的元音字母和空格字符移除,生成了一个含义模糊的短句:

let puzzleInput = "great minds think alike"
var puzzleOutput = ""
for character in puzzleInput {
    switch character {
    case "a", "e", "i", "o", "u", " ":
        continue
    default:
        puzzleOutput.append(character)
    }
}
print(puzzleOutput)
    // 输出“grtmndsthnklk”


在上面的代码中,只要匹配到元音字母或者空格字符,就调用 continue 语句,使本次循环结束,重新开始下次循环。这种行为使 switch 匹配到元音字母和空格字符时不做处理,而不是让每一个匹配到的字符都被打印。


Break



break 语句会立刻结束整个控制流的执行。break 可以在 switch 或循环语句中使用,用来提前结束 switch 或循环语句。


循环语句中的 break


当在一个循环体中使用 break 时,会立刻中断该循环体的执行,然后跳转到表示循环体结束的大括号(})后的第一行代码。不会再有本次循环的代码被执行,也不会再有下次的循环产生。


Switch 语句中的 break


当在一个 switch 代码块中使用 break 时,会立即中断该 switch 代码块的执行,并且跳转到表示 switch 代码块结束的大括号(})后的第一行代码。


这种特性可以被用来匹配或者忽略一个或多个分支。因为 Swift 的 switch 需要包含所有的分支而且不允许有为空的分支,有时为了使你的意图更明显,需要特意匹配或者忽略某个分支。那么当你想忽略某个分支时,可以在该分支内写上 break 语句。当那个分支被匹配到时,分支内的 break 语句立即结束 switch 代码块。


注意

当一个 switch 分支仅仅包含注释时,会被报编译时错误。注释不是代码语句而且也不能让 switch 分支达到被忽略的效果。你应该使用 break 来忽略某个分支。


下面的例子通过 switch 来判断一个 Character 值是否代表下面四种语言之一。为了简洁,多个值被包含在了同一个分支情况中。

let numberSymbol: Character = "三"  // 简体中文里的数字 3
var possibleIntegerValue: Int?
switch numberSymbol {
case "1", "١", "一", "๑":
    possibleIntegerValue = 1
case "2", "٢", "二", "๒":
    possibleIntegerValue = 2
case "3", "٣", "三", "๓":
    possibleIntegerValue = 3
case "4", "٤", "四", "๔":
    possibleIntegerValue = 4
default:
    break
}
if let integerValue = possibleIntegerValue {
    print("The integer value of \(numberSymbol) is \(integerValue).")
} else {
    print("An integer value could not be found for \(numberSymbol).")
}
// 输出“The integer value of 三 is 3.”


这个例子检查 numberSymbol 是否是拉丁,阿拉伯,中文或者泰语中的 14 之一。如果被匹配到,该 switch 分支语句给 Int? 类型变量 possibleIntegerValue 设置一个整数值。


switch 代码块执行完后,接下来的代码通过使用可选绑定来判断 possibleIntegerValue 是否曾经被设置过值。因为是可选类型的缘故,possibleIntegerValue 有一个隐式的初始值 nil,所以仅仅当 possibleIntegerValue 曾被 switch 代码块的前四个分支中的某个设置过一个值时,可选的绑定才会被判定为成功。


在上面的例子中,想要把 Character 所有的的可能性都枚举出来是不现实的,所以使用 default 分支来包含所有上面没有匹配到字符的情况。由于这个 default 分支不需要执行任何动作,所以它只写了一条 break 语句。一旦落入到 default 分支中后,break 语句就完成了该分支的所有代码操作,代码继续向下,开始执行 if let 语句。


贯穿(Fallthrough)



在 Swift 里,switch 语句不会从上一个 case 分支跳转到下一个 case 分支中。相反,只要第一个匹配到的 case 分支完成了它需要执行的语句,整个 switch 代码块就完成了它的执行。相比之下,C语言要求你显式地插入 break 语句到每个 case 分支的末尾来阻止自动落入到下一个 case 分支中。Swift 的这种避免默认落入到下一个分支中的特性意味着它的 switch 功能要比 C语言的更加清晰和可预测,可以避免无意识地执行多个 case 分支从而引发的错误。


如果你确实需要 C 风格的贯穿的特性,你可以在每个需要该特性的 case 分支中使用 fallthrough 关键字。下面的例子使用 fallthrough 来创建一个数字的描述语句。

let integerToDescribe = 5
var description = "The number \(integerToDescribe) is"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
    description += " a prime number, and also"
    fallthrough
default:
    description += " an integer."
}
print(description)
// 输出“The number 5 is a prime number, and also an integer.”


这个例子定义了一个 String 类型的变量 description 并且给它设置了一个初始值。函数使用 switch 逻辑来判断 integerToDescribe 变量的值。当 integerToDescribe 的值属于列表中的质数之一时,该函数在 description 后添加一段文字,来表明这个数字是一个质数。然后它使用 fallthrough 关键字来“贯穿”到 default 分支中。default 分支在 description 的最后添加一段额外的文字,至此 switch 代码块执行完了。


如果 integerToDescribe 的值不属于列表中的任何质数,那么它不会匹配到第一个 switch 分支。而这里没有其他特别的分支情况,所以 integerToDescribe 匹配到 default 分支中。


当 switch 代码块执行完后,使用 print(_:separator:terminator:) 函数打印该数字的描述。在这个例子中,数字 5 被准确的识别为了一个质数。


注意:


fallthrough 关键字不会检查它下一个将会落入执行的 case 中的匹配条件。fallthrough 简单地使代码继续连接到下一个 case 中的代码,这和 C 语言标准中的 switch 语句特性是一样的。


带标签的语句



在 Swift 中,你可以在循环体和条件语句中嵌套循环体和条件语句来创造复杂的控制流结构。并且,循环体和条件语句都可以使用 break 语句来提前结束整个代码块。因此,显式地指明 break 语句想要终止的是哪个循环体或者条件语句,会很有用。类似地,如果你有许多嵌套的循环体,显式指明 continue 语句想要影响哪一个循环体也会非常有用。


为了实现这个目的,你可以使用标签(statement label)来标记一个循环体或者条件语句,对于一个条件语句,你可以使用 break 加标签的方式,来结束这个被标记的语句。对于一个循环语句,你可以使用 break 或者 continue 加标签,来结束或者继续这条被标记语句的执行。


声明一个带标签的语句是通过在该语句的关键词的同一行前面放置一个标签,作为这个语句的前导关键字(introducor keyword),并且该标签后面跟随一个冒号。下面是一个针对 while 循环体的标签语法,同样的规则适用于所有的循环体和条件语句。

label name: while condition {
     statements
 }


注:


按照常规语言,双重循环需要添加大量 break,使得代码不易读。

swift 则可以给循环起名字,通过 break+名字,来结束掉某层循环。

findAnswer: 
for m in 1...300{
       for n in 1...300{
               if m*m*m*m-n*n==15*m*n{
                      print(m,n)
                      break findAnswer
               }
       }
}


目录
相关文章
|
Swift iOS开发
14 在Swift中进行循环控制
在Swift中进行循环控制
84 0
|
11天前
|
存储 网络协议 搜索推荐
宏函数的代码替换机制会对程序的可移植性产生什么影响
宏函数的代码替换机制可能导致程序可移植性降低,因为它在预处理阶段直接替换文本,可能引发类型不匹配、副作用等问题,不同编译器和平台表现不一。
|
Swift iOS开发
15 如何在Swift中进行控制转移
如何在Swift中进行控制转移
45 0
|
Swift 数据安全/隐私保护
40 Swift中代码访问权限控制
Swift中代码访问权限控制
74 0
|
6月前
|
存储 Swift
swift值状态
swift值状态
43 1
|
6月前
|
Swift
Swift 的控制流结构
Swift 的控制流结构
44 1
|
Swift iOS开发
Swift - 如何用Reachability来混编判断网络状况
Swift - 如何用Reachability来混编判断网络状况
296 0
|
人工智能 前端开发 开发工具
Swift实用小册05:条件、循环和控制转移语句的使用
Swift实用小册05:条件、循环和控制转移语句的使用
206 0
Swift实用小册05:条件、循环和控制转移语句的使用
|
Swift 编译器
Swift - 实例对象调用协议方法优先级分析/ witness_methos witness_table分析
本文主要探究: 当一个类遵循了协议,且协议和类都有方法实现时,实例对象调用方法的优先顺序
Swift - 实例对象调用协议方法优先级分析/ witness_methos witness_table分析
|
存储
Swift5.1—检查协议一致性
Swift5.1—检查协议一致性
276 0