7.1 分支语句
分支语句提供了一种控制机制,使得程序具有了“判断能力”,能够像人类的大脑一样分析问题。分支语句又称条件语句,条件语句使部分程序可根据某些表达式的值被有选择地执行。Swift编程语言提供了if和switch两种分支语句。
7.1.1 条件语句if
由if语句引导的选择结构有if结构、if else结构和else if结构3种。
if结构
如果条件表达式为true就执行语句组,否则就执行if结构后面的语句。与C和Objective-C语言不同的是,即便语句组是单句,也不能省略大括号。语法结构如下:
if 条件表达式 {语句组}
if结构示例代码如下:
var score = 95if score >= 85 {println("您真优秀!")}if score < 60 {println("您需要加倍努力!")}if score >= 60 && score < 85 {println("您的成绩还可以,仍需继续努力!")}
程序运行结果如下:
"您真优秀!"
if else结构
所有的语言都有这个结构,而且结构的格式基本相同,语句如下:
if 条件表达式 {语句组1} else {语句组2 }
当程序执行到if语句时,先判断条件表达式,如果值为true,则执行语句组1,然后跳过else语句及语句组2,继续执行后面的语句。如果条件表达式的值为false,则忽略语句组1而直接执行语句组2,然后继续执行后面的语句。
if else结构示例代码如下:
var score = 95if score < 60 {println("不及格")} else {println("及格")}
程序运行结果如下:
"及格"
else if结构
else if结构如下:
if 条件表达式1 {语句组1} else if 条件表达式2 {语句组2} else if 条件表达式3 {语句组3...} else if 条件表达式n {语句组n} else {语句组n+1}
可以看出,else if结构实际上是if else结构的多层嵌套,它明显的特点就是在多个分支中只执行一个语句组,而其他分支都不执行,所以这种结构可以用于有多种判断结果的分支中。
else if结构示例代码如下:
let testscore = 76var grade:Characterif testscore >= 90 {grade = "A"} else if testscore >= 80 {grade = "B"} else if testscore >= 70 {grade = "C"} else if testscore >= 60 {grade = "D"} else {grade = "F"}println("Grade = \(grade)")
输出结果如下:
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语句基本形式的语法结构,如下所示:
switch 条件表达式{case 值1:语句组1case 值2,值3:语句组2case 值3:语句组3...case 判断值n:语句组ndefault:语句组n+1}
每个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语句基本形式示例代码如下:
let testscore = 86var grade:Characterswitch testscore / 10 { ①case 9:grade = "优"case 8:grade = "良"case 7,6: ②grade = "中"default:grade = "差"}println("Grade = \(grade)")
输出结果如下:
Grade = 良
上述代码将100分制转换为:“优”、“良”、“中”、“差”评分制。第①行计算表达式获得0~9分数值。第②行代码中的7,6是将两个值放在一个case。
Swift中的switch不仅可以比较整数类型还可以比较浮点和字符等类型。下面是一个比较浮点数的示例:
let value = 1.000var desc:Stringswitch value {case 0.0:desc = "最小值"case 0.5:desc = "中值"case 1.0:desc = "最大值"default:desc = "其他值"}println("说明 = \(desc)")
输出结果如下:
说明 = 最大值
结果说明1.000是与1.0相等的。
下面是一个字符比较示例:
let level = "优"var desc:Stringswitch level {case "优":desc = "90分以上"case "良":desc = "80分~90分"case "中":desc = "70分~80分"case "差":desc = "低于60分"default:desc = "无法判断"}println("说明 = \(desc)")
输出结果:
说明 = 90分以上
7.1.3 在switch中使用范围匹配
对于数字类型的比较,switch中的case还可以指定一个范围,如果要比较的值在这个范围内,则执行这个分支。示例代码如下:
let testscore = 80var grade:Characterswitch testscore {case 90...100: ①grade = "优"case 80..<90: ②grade = "良"case 60..<80: ③grade = "中"case 0..<60: ④grade = "差"default: ⑤grade = "无"}println("Grade = \(grade)")
输出结果如下:
说明:良
上述代码通过判断成绩范围,给出“优”、“良”、“中”和“差”评分标准,默认值“无”是分数不在上述范围内时给出的。
提示 在定义范围的时候,我们使用了闭区间(
…)和半闭区间(..<)运算符。代码第①行90…100范围使用闭区间表示,即90 ≤ grade ≤100的情况,包含两个临界值。而第②、③、④行代码的范围使用了半闭区间,因此80..<90表示 80 ≤ grade < 90,包含下临界值,不包含上临界值。
7.1.4 在switch中比较元组类型
元组作为多个值的表示方式也可以在switch中进行比较。switch使用元组非常灵活,字段可以是普通值,也可以是范围。
示例代码如下:
var student = (id:"1002", name:"李四", age:32, ChineseScore:80, EnglishScore:89) ①var desc:Stringswitch student {case (_, _, _, 90...100, 90...100): ②desc = "优"case (_, _, _, 80..<90, 80.. <90): ③desc = "良"case (_, _, _, 60..<80, 60..<80): ④desc = "中"case (_, _, _, 60..<80, 90...100), (_, _, _, 90...100, 60..<80): ⑤desc = "偏科"case (_, _, _, 0.. <80, 90...100), (_, _, _, 90...100, 0..<80): ⑥desc = "严重偏科"default:desc = "无"}println("说明:\(desc)")
输出结果如下:
说明:良
上述代码第①行声明并初始化学生元组,它有5个字段,其中id为学号,name为姓名,age为年龄,ChineseScore为语文成绩,EnglishScore为英语成绩。在这个示例中,我们只是比较学生的语文成绩和英语成绩,其他的字段不比较,我们可以在case中使用下划线(_)忽略其中的字段值。第②行代码中(_, _, _, 90…100, 90…100)的前三个下划线(_)忽略了id、name和age3个字段,switch不比较它们的值,只比较ChineseScore成绩是否属于90…100范围,比较EnglishScore成绩是否属于90…100范围。代码第③行和第④行也是类似的。
代码第⑤行和第⑥行有些特殊,这里使用了逗号(,)分隔两个元组值,这表示“或”的关系,即(_, _, _, 60..<80, 90…100)或(_, _, _, 90…100, 60..<80)的情况。
在switch中使用元组还可以使用值绑定和where语句。
- 值绑定
使用元组的时候还可以在case分支中将匹配的值绑定到一个临时的常量或变量,这些常量或变量能够在该分支里使用,这被称为值绑定。
示例代码如下:
var student = (id:"1002", name:"李四", age:32, ChineseScore:90, EnglishScore:91)var desc:Stringswitch student {case (_, _, let age, 90...100, 90...100): ①if (age > 30) { ②desc = "老优"} else {desc = "小优"}case (_, _, _, 80..<90, 80..<90):desc = "良"case (_, _, _, 60..<80, 60..<80):desc = "中"case (_, _, _, 60..<80, 90...100), (_, _, _, 90...100, 60..<80):desc = "偏科"case (_, _, _, 0..<80, 90...100), (_, _, _, 90...100, 0..<80):desc = "严重偏科"default:desc = "无"}println("说明:\(desc)")
输出结果如下:
说明:老优
本示例还是关于成绩的问题,其中第①行代码中的let age就是值绑定,我们在case中声明了一个age常量,然后age常量就可以在该分支中使用了,我们在第②行代码使用arge常量,判断age > 30。
where语句
在绑定值的情况下,还可以在case中使用where语句,进行条件的过滤,类似于SQL语句1中的where子句。
1结构化查询语言(Structured Query Language,SQL),是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;同时也是数据库脚本文件的扩展名。——百度百科 http://baike.baidu.com/view/595350.htm
示例代码如下:
var student = (id:"1002", name:"李四", age:32, ChineseScore:90, EnglishScore:91)var desc:Stringswitch student {case (_, _, let age, 90...100, 90...100) where age > 0: ①desc = "优"case (_, _, _, 80..<90, 80..<90):desc = "良"case (_, _, _, 60..<80, 60..<80):desc = "中"case (_, _, _, 60..<80, 90...100), (_, _, _, 90...100, 60..<80):desc = "偏科"case (_, _, _, 0..<80, 90...100), (_, _, _, 90...100, 0..<80):desc = "严重偏科"default:desc = "无"}println("说明:\(desc)")
输出结果如下:
说明:优
本示例是对上个示例的修改,代码第①行中的let age就是值绑定,然后我们在case后面使用了where age > 0,过滤掉元组age字段小于0的数据。
