循环控制
for-in 循环
1、使用 for-in 循环来遍历序列,比如一个范围的数字:
|
|
打印结果:
|
|
2、遍历字符串中的字符:
|
|
打印结果:
|
|
3、遍历数组中的元素:
|
|
打印结果:
|
|
for-in 遍历字典
1、字典在 for-in 遍历时,每一个元素都是一个元组 (key, value)
。
|
|
打印结果:
|
|
2、可以在 for-in 循环体中,使用显示命名常量来分解元组成员:
|
|
打印结果:
|
|
3、在不需要遍历到的每一个值时,可以使用下划线 _
取代遍历名以忽略值:
|
|
for-in 分段区间
使用 stride()
函数来跳过不想要的标记。
stride(from:to:by:)
:开区间
|
|
打印结果:
|
|
stride(from:through:by:)
:闭区间
|
|
打印结果:
|
|
while 循环
Swift 中的 repeat-while 循环。
|
|
打印结果:
|
|
OC 中的 do-while 循环:
|
|
打印结果:
|
|
OC 中的 while 循环
|
|
打印结果:
|
|
switch
switch 语句会将一个值与多个可能的模式匹配,然后基于第一个成功匹配的模式来执行合适的代码块。
switch 语句一定得是全面的,在给定类型里,每一个值都要被考虑到,并且匹配到一个对应的 switch case 里。如果无法提供一个 switch case 所有可能的值,则可以用关键字 default 标记,即默认匹配所有未明确的值。default 关键字必须在所有 case 的最后。
|
|
如果没有 default 关键字,则会报错:
Objective-C 中的 switch 语句如果不全面,仍然可以运行
1234567891011 char c = 'z';switch (c) {case 'a':NSLog(@"The first letter of the alphabet");break;case 'z':NSLog(@"The last letter of the alphabet");break;}// Prints "The last letter of the alphabet"
没有隐式贯穿
相比 C 和 Objective-C 里的 switch 语句来说,Swift 里的 switch 语句不会默认从匹配 case 的末尾贯穿到下一个 case 里。相反,整个 switch 语句会在匹配到第一个 switch 的 case 执行完毕之后退出,不再需要显式的 break 语句。
C 和 Objective-C 里的 switch 的隐式贯穿:
123456789101112 char c = 'z';switch (c) {case 'a':NSLog(@"The first letter of the alphabet");case 'z':NSLog(@"The last letter of the alphabet");default:NSLog(@"Some other character");}// The last letter of the alphabet// Some other character
因为 Swift 的 switch 语句没有隐式贯穿,所以每一个 case 的函数体必须包含至少一个可执行的语句。
因为 Swift 的 switch 语句没有隐式贯穿,所以想要实现匹配多个值的情况,可以用逗号分隔,并且可以写成多行。
|
|
区间匹配
switch 的 case 的值可以在一个区间中匹配。
|
|
元组匹配
可以使用元组来在一个 switch 语句中测试多个值,使用下划线 _
来表明匹配所有可能的值。
匹配在 (-2, 2) 组成的盒子内的点:
|
|
值绑定
switch 的 case 可以将匹配到的值临时绑定为一个常量或者变量,来给 case 的函数体使用。
|
|
如果使用 var
关键字,临时的变量就会以合适的值来创建并初始化。这个变量的任何改变都只会在 case 的函数体内有效。
|
|
where 分句
switch case 可以使用 where
分句来检查是否符合特定的约束。
匹配在两条直线上的点:
|
|
复合匹配
多种情形共享同一个函数体的多个情况可以在 case 后写多个模式来复合,在每个模式之间用逗号分隔。如果任何一个模式匹配了,那么这个情况都会被认为是匹配的。如果模式太长,可以把它们写成多行。
|
|
复合匹配 - 值绑定
复合匹配同样可以包含值绑定。所有复合匹配的模式都必须包含相同的值绑定集合,并且复合情况中的每一个绑定都得有相同的类型格式。这才能确保无论复合匹配的哪部分命中了,在函数体中的代码都能访问到绑定的值,并且值的类型也都相同。
|
|
控制转移
continue
continue
语句表示让循环停止当前遍历,开始下一次遍历。并不是离开整个循环。
|
|
打印结果:
|
|
break
break 语句会立即结束整个控制流语句。在需要提前结束 switch 或者其它循环语句时,可以使用 break。
break 会立即结束整个循环的执行,并且转移控制到循环结束花括号(}
)后的第一行代码上。结束整个循环,表示当前遍历循环里的其它代码都不会被执行,并且余下的遍历循环也不会开始了。
|
|
打印结果:
|
|
在 switch
语句里使用 break
时,switch
语句会立即结束执行,并且转移控制到 switch
语句结束花括号(}
)之后的第一行代码上。
|
|
fallthrough
Swift 的 switch
语句不支持隐私贯穿,可以通过关键字 fallthrough
显式实现贯穿行为。
|
|
语句标签
可以使用语句标签给循环语句或者条件语句做标记。在一个条件语句中,可以使用语句标签配合 break
语句来结束被标记的语句。在循环语句中,你可以使用语句标签来配合 break
或者 continue
语句来结束或者继续执行被标记的语句。
|
|
guard
guard
语句,类似于 if
语句,基于布尔值表达式来执行语句。使用 guard
语句来要求一个条件必须是真才能执行 guard
之后的语句。与 if
语句不同,guard
语句总是有一个 else
分句——else
分句里的代码会在条件不为真的时候执行:
在编写条件语句的时候,左边的代码间距应该是一个“黄金”或者“快乐”的大道。不要嵌套 if
语句,多个 return
语句可能是更好的,这样可以避免圈复杂度(Cyclomatic Complexity),并且让代码更加容易阅读。因为重要部分没有嵌套在分支上,可以很清楚的找到相关代码。
推荐写法:
|
|
不推荐写法:
|
|
或者:
|
|
或者:
|
|
相关文档:
https://github.com/objc-zen/objc-zen-book
https://docs.swift.org/swift-book/LanguageGuide/ControlFlow.html
应用1——验证 ip 地址的格式是否正确
例1、使用 if
语句实现
|
|
例2、使用 guard 语句(注意左侧的黄金大道)实现
|
|
应用2——检查 API 可用性
Swift 拥有内置的 API 可用性的检查功能,能够确保使用不可用的 API。
可以在 if 或者 guard 语句中使用一个可用性条件来有条件地执行代码。
|
|
模式和模式匹配
模式:代表单个值或者复合值的结构。例如,x
的结构代表单个值的模式;元组 (x, y)
的结构是由逗号分隔的,包含两个元素的列表(元组模式)。
模式匹配:模式代表一种值的结构,而不是特定的某个值,可以利用模式来匹配各种各样的值。例如,(x, y)
可以匹配元组 (1, 2)
,以及任何两个元素的元组。
除了利用模式匹配一个值以外,也可以从复合值中提取出部分或全部值,然后分别把各个部分的值和一个常量或者变量对应起来。
模式分类
Swift 中的模式分为两类:一种能成功匹配任何类型的值,另一种在运行时匹配某个特定值时可能会失败。
第一类模式:用于解构简单变量、常量和可选绑定中的值。此类模式包括通配符模式、标识符模式,以及包含前两种模式的值绑定模式和元组模式。可以为这类模式指定一个类型标注,从而限制它们只能匹配某种特定类型的值。
第二类模式:用于全模式匹配,这种情况下匹配的值在运行时可能不存在。此类模式包括枚举用例模式、可选模式、表达式模式和类型转换模式。在
switch
语句的case
标签中,do
语句的catch
子句中,或者在if
、while
、guard
和for-in
语句的cas
e 条件句中使用这类模式。
通配符模式(Wildcard Pattern)
通配符模式:由一个下划线 _
构成,用于匹配并忽略任何值。如在便利时,忽略被匹配的值时可以使用该模式。
|
|
标识符模式(Identifier Pattern)
标识符模式:匹配任何值,并将匹配的值和一个变量或常量绑定起来。如定义一个常量:
|
|
值绑定模式(Value-Binding Pattern)
值绑定模式:把匹配到的值绑定给一个变量或常量。如把匹配到的值绑定给常量时,用关键字 let
,绑定给变量时,用关键字 var
。
|
|
元组模式(Tuple Pattern)
元组模式:是有逗号分隔的,具有零个或多个模式的列表,并由一对圆括号括起来(如:(x, y)
)。元组模式匹配相应元组类型的值。
可以使用类型标注限制一个元组模式能匹配哪种元组类型。例如,在常量声明 let(x, y): (Int, Int) = (1, 2)
中的元组模式 (x, y): (Int, Int)
只能匹配两个元素都是 Int
类型的元组。
当元组模式被用于 for-in
语句或者常量和变量声明时,它仅可以包含通配符模式、标识符模式、可选模式或者其他包含这些模式的元组模式。
例如,在 for-in
语句中,使用通配符模式匹配 y == 0
的元组。
|
|
打印结果:
|
|
没有正确使用元组模式则会报错,如 (x, 0)
不是正确的元组模式:
模式都是字母,而不是一个确切的数字,0 是数字,可以用 y
代替 0。
枚举用例模式(Enumeration Case Pattern)
枚举用例模式:匹配现有的某个枚举类型的某个用例。枚举用例模式出现在 switch
语句中的 case
标签中,以及 if
、while
、guard
和 for-in
语句的 case
条件中。
可选项目模式(Optional Pattern)
可选项模式匹配 Optional<Wrapped>
枚举在 some(Wrapped)
中包装的值。
|
|
或者
|
|
可选项模式为 for-in
语句提供了一种迭代数组的简便方式,只为数组中非 nil
的元素执行循环体。
|
|
打印结果:
|
|
类型转换模式(Type-Casting Pattern)
有两种类型转换模式,is 模式和 as 模式。is 模式只出现在 switch 语句中的 case 标签中。
is
模式:当一个值的类型在运行时和is
模式右边的指定类型一致,或者是其子类的情况下,才会匹配这个值。is
模式和is
运算符有相似表现,它们都进行类型转换,但是is
模式没有返回类型。as
模式:当一个值的类型在运行时和as
模式右边的指定类型一致,或者是其子类的情况下,才会匹配这个值。如果匹配成功,被匹配的值的类型被转换成as
模式右边指定的类型。
|
|
表达式模式(Expression Pattern)
表达式模式代表表达式的值。表达式模式只出现在 switch 语句中的 case 标签中。
表达式模式代表的表达式,会使用 Swift 标准库中的 ~=
运算符,与输入表达式的值进行比较。如果 ~=
运算符返回 true,则匹配成功。
默认情况下,~=
运算符使用 ==
运算符来比较两个相同类型的值。它也可以将一个整型数值与一个 Range 实例中的一段整数区间做匹配。
|
|
可以重载 ~=
运算符来提供自定义的表达式匹配行为:
|
|
自定义类型默认也是无法进行表达式模式匹配的,也需要重载 ~=
运算符。
|
|