7.1 分支语句

分支语句提供了一种控制机制,使得程序具有了“判断能力”,能够像人类的大脑一样分析问题。分支语句又称条件语句,条件语句使部分程序可根据某些表达式的值被有选择地执行。Swift编程语言提供了ifswitch两种分支语句。

7.1.1 条件语句if

if语句引导的选择结构有if结构、if else结构和else if结构3种。

  1. if结构

如果条件表达式为true就执行语句组,否则就执行if结构后面的语句。与C和Objective-C语言不同的是,即便语句组是单句,也不能省略大括号。语法结构如下:

  1. if 条件表达式 {
  2. 语句组
  3. }

if结构示例代码如下:

  1. var score = 95
  2. if score >= 85 {
  3. println("您真优秀!")
  4. }
  5. if score < 60 {
  6. println("您需要加倍努力!")
  7. }
  8. if score >= 60 && score < 85 {
  9. println("您的成绩还可以,仍需继续努力!")
  10. }

程序运行结果如下:

  1. "您真优秀!"
  1. if else结构

所有的语言都有这个结构,而且结构的格式基本相同,语句如下:

  1. if 条件表达式 {
  2. 语句组1
  3. } else {
  4. 语句组2 }

当程序执行到if语句时,先判断条件表达式,如果值为true,则执行语句组1,然后跳过else语句及语句组2,继续执行后面的语句。如果条件表达式的值为false,则忽略语句组1而直接执行语句组2,然后继续执行后面的语句。

if else结构示例代码如下:

  1. var score = 95
  2. if score < 60 {
  3. println("不及格")
  4. } else {
  5. println("及格")
  6. }

程序运行结果如下:

  1. "及格"
  1. else if结构

else if结构如下:

  1. if 条件表达式1 {
  2. 语句组1
  3. } else if 条件表达式2 {
  4. 语句组2
  5. } else if 条件表达式3 {
  6. 语句组3
  7. ...
  8. } else if 条件表达式n {
  9. 语句组n
  10. } else {
  11. 语句组n1
  12. }

可以看出,else if结构实际上是if else结构的多层嵌套,它明显的特点就是在多个分支中只执行一个语句组,而其他分支都不执行,所以这种结构可以用于有多种判断结果的分支中。

else if结构示例代码如下:

  1. let testscore = 76
  2. var grade:Character
  3. if testscore >= 90 {
  4. grade = "A"
  5. } else if testscore >= 80 {
  6. grade = "B"
  7. } else if testscore >= 70 {
  8. grade = "C"
  9. } else if testscore >= 60 {
  10. grade = "D"
  11. } else {
  12. grade = "F"
  13. }
  14. println("Grade = \(grade)")

输出结果如下:

  1. Grade = C

其中,var grade:Character是声明字符变量,然后经过判断最后结果是C

7.1.2 多分支语句switch

switch语句也称开关语句,它提供多分支程序结构。

Swift彻底地颠覆了自C语言以来大家对于switch的认知,这个颠覆表现在以下两个方面。

一方面,在C、C++、Objective-C、Java甚至是C#语言中,switch语句只能比较离散的单个整数(或可以自动转换为整数)变量,而Swift中的switch语句可以使用整数、浮点数、字符、字符串和元组等类型,而且它的数值可以是离散的也可以是连续的范围。

另一方面,Swift中的switch语句case分支不需要显式地添加break语句,分支执行完成就会跳出switch语句。

下面我们先介绍一下switch语句基本形式的语法结构,如下所示:

  1. switch 条件表达式{
  2. case 1
  3. 语句组1
  4. case 2,值3
  5. 语句组2
  6. case 3:语句组3
  7. ...
  8. case 判断值n
  9. 语句组n
  10. default
  11. 语句组n1
  12. }

每个case后面可以跟一个或多个值,多个值之间用逗号分隔。每个switch必须有一个default语句,它放在所有分支后面。每个case中至少要有一条语句。

当程序执行到switch语句时,先计算条件表达式的值,假设值为A,然后拿A与第1个case语句中的值1进行匹配,如果匹配则执行语句组1,语句组执行完成就跳出switch,不像C语言那样只有遇到break才跳出switch;如果A没有与第1个case语句匹配,则与第2个case语句进行匹配,如果匹配则执行语句组2,以此类推,直到执行语句组n。如果所有的case语句都没有执行,就执行default的语句组n+1,这时才跳出switch

switch语句基本形式示例代码如下:

  1. let testscore = 86
  2. var grade:Character
  3. switch testscore / 10 {
  4. case 9:
  5. grade = "优"
  6. case 8:
  7. grade = "良"
  8. case 7,6:
  9. grade = "中"
  10. default:
  11. grade = "差"
  12. }
  13. println("Grade = \(grade)")

输出结果如下:

  1. Grade =

上述代码将100分制转换为:“优”、“良”、“中”、“差”评分制。第①行计算表达式获得0~9分数值。第②行代码中的7,6是将两个值放在一个case

Swift中的switch不仅可以比较整数类型还可以比较浮点和字符等类型。下面是一个比较浮点数的示例:

  1. let value = 1.000
  2. var desc:String
  3. switch value {
  4. case 0.0:
  5. desc = "最小值"
  6. case 0.5:
  7. desc = "中值"
  8. case 1.0:
  9. desc = "最大值"
  10. default:
  11. desc = "其他值"
  12. }
  13. println("说明 = \(desc)")

输出结果如下:

  1. 说明 = 最大值

结果说明1.000是与1.0相等的。

下面是一个字符比较示例:

  1. let level = "优"
  2. var desc:String
  3. switch level {
  4. case "优":
  5. desc = "90分以上"
  6. case "良":
  7. desc = "80分~90分"
  8. case "中":
  9. desc = "70分~80分"
  10. case "差":
  11. desc = "低于60分"
  12. default:
  13. desc = "无法判断"
  14. }
  15. println("说明 = \(desc)")

输出结果:

  1. 说明 = 90分以上

7.1.3 在switch中使用范围匹配

对于数字类型的比较,switch中的case还可以指定一个范围,如果要比较的值在这个范围内,则执行这个分支。示例代码如下:

  1. let testscore = 80
  2. var grade:Character
  3. switch testscore {
  4. case 90...100:
  5. grade = "优"
  6. case 80..<90:
  7. grade = "良"
  8. case 60..<80:
  9. grade = "中"
  10. case 0..<60:
  11. grade = "差"
  12. default:
  13. grade = "无"
  14. }
  15. println("Grade = \(grade)")

输出结果如下:

  1. 说明:良

上述代码通过判断成绩范围,给出“优”、“良”、“中”和“差”评分标准,默认值“无”是分数不在上述范围内时给出的。

提示 在定义范围的时候,我们使用了闭区间()和半闭区间(..<)运算符。代码第①行90…100范围使用闭区间表示,即90 ≤ grade ≤100的情况,包含两个临界值。而第②、③、④行代码的范围使用了半闭区间,因此80..<90表示 80 ≤ grade < 90,包含下临界值,不包含上临界值。

7.1.4 在switch中比较元组类型

元组作为多个值的表示方式也可以在switch中进行比较。switch使用元组非常灵活,字段可以是普通值,也可以是范围。

示例代码如下:

  1. var student = (id:"1002", name:"李四", age:32, ChineseScore:80, EnglishScore:89) ①
  2. var desc:String
  3. switch student {
  4. case (, , _, 90...100, 90...100): ②
  5. desc = "优"
  6. case (, , _, 80..<90, 80.. <90): ③
  7. desc = "良"
  8. case (, , _, 60..<80, 60..<80): ④
  9. desc = "中"
  10. case (, , _, 60..<80, 90...100), (, , _, 90...100, 60..<80): ⑤
  11. desc = "偏科"
  12. case (, , _, 0.. <80, 90...100), (, , _, 90...100, 0..<80): ⑥
  13. desc = "严重偏科"
  14. default:
  15. desc = "无"
  16. }
  17. println("说明:\(desc)")

输出结果如下:

  1. 说明:良

上述代码第①行声明并初始化学生元组,它有5个字段,其中id为学号,name为姓名,age为年龄,ChineseScore为语文成绩,EnglishScore为英语成绩。在这个示例中,我们只是比较学生的语文成绩和英语成绩,其他的字段不比较,我们可以在case中使用下划线(_)忽略其中的字段值。第②行代码中(, , _, 90…100, 90…100)的前三个下划线(_)忽略了idnameage3个字段,switch不比较它们的值,只比较ChineseScore成绩是否属于90…100范围,比较EnglishScore成绩是否属于90…100范围。代码第③行和第④行也是类似的。

代码第⑤行和第⑥行有些特殊,这里使用了逗号(,)分隔两个元组值,这表示“或”的关系,即(, , _, 60..<80, 90…100)(, , _, 90…100, 60..<80)的情况。

在switch中使用元组还可以使用值绑定和where语句。

  1. 值绑定

使用元组的时候还可以在case分支中将匹配的值绑定到一个临时的常量或变量,这些常量或变量能够在该分支里使用,这被称为值绑定

示例代码如下:

  1. var student = (id:"1002", name:"李四", age:32, ChineseScore:90, EnglishScore:91)
  2. var desc:String
  3. switch student {
  4. case (, , let age, 90...100, 90...100):
  5. if (age > 30) {
  6. desc = "老优"
  7. } else {
  8. desc = "小优"
  9. }
  10. case (, , _, 80..<90, 80..<90):
  11. desc = "良"
  12. case (, , _, 60..<80, 60..<80):
  13. desc = "中"
  14. case (, , _, 60..<80, 90...100), (, , _, 90...100, 60..<80):
  15. desc = "偏科"
  16. case (, , _, 0..<80, 90...100), (, , _, 90...100, 0..<80):
  17. desc = "严重偏科"
  18. default:
  19. desc = "无"
  20. }
  21. println("说明:\(desc)")

输出结果如下:

  1. 说明:老优

本示例还是关于成绩的问题,其中第①行代码中的let age就是值绑定,我们在case中声明了一个age常量,然后age常量就可以在该分支中使用了,我们在第②行代码使用arge常量,判断age > 30

  1. where语句

在绑定值的情况下,还可以在case中使用where语句,进行条件的过滤,类似于SQL语句1中的where子句。

1结构化查询语言(Structured Query Language,SQL),是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;同时也是数据库脚本文件的扩展名。——百度百科 http://baike.baidu.com/view/595350.htm

示例代码如下:

  1. var student = (id:"1002", name:"李四", age:32, ChineseScore:90, EnglishScore:91)  
  2. var desc:String
  3. switch student {
  4. case (, , let age, 90...100, 90...100) where age > 0: ①
  5. desc = "优"
  6. case (, , _, 80..<90, 80..<90):
  7. desc = "良"
  8. case (, , _, 60..<80, 60..<80):
  9. desc = "中"
  10. case (, , _, 60..<80, 90...100), (, , _, 90...100, 60..<80):
  11. desc = "偏科"
  12. case (, , _, 0..<80, 90...100), (, , _, 90...100, 0..<80):
  13. desc = "严重偏科"
  14. default:
  15. desc = "无"
  16. }
  17. println("说明:\(desc)")

输出结果如下:

  1. 说明:优

本示例是对上个示例的修改,代码第①行中的let age就是值绑定,然后我们在case后面使用了where age > 0,过滤掉元组age字段小于0的数据。