1. Swift的控制流:
1) 基本上是C语言的超集,增加了一些更强大的功能;
2) 顺序执行:一切正常;
3) 分支:if-else、if-else if-else、switch(switch功能更加强大)
4) 循环:while、do-while、for、for in
5) 跳转:break、continue、return、falltrough(用于模拟switch中不是break的情形,Swift中的case不加break就跟C语言加break一样)、where(用于switch中的只绑定,使switch具有SQL语句中where的条件过滤功能)
2. if系列:
1) !!Swift中所有控制语句的代码块即使只有一条语句也得用{}括起来,这和C和OC不一样!
2) !!Swift中控制语句的控制条件都可以不加括号(),当然加上去也没事,会是程序更加清晰,但是不建议加括号,就使用Swift的风格,更加简洁!
3) if系列和传统语言一样而且前面已经举过很多例子了,所以这里就不累述了!
3. switch:
1) 支持多值匹配,并且默认不使用break跳出switch,并且每个选项至少要有一条语句:
let score = 86 var grade: Character switch score / 10 { case 10, 9: grade = "优" // 多个值之间用逗号,分开 case 8: grade = "良" // 和C语言不一样,不需要break就能自动跳出switch case 7, 6: grade = "中" // case 5: // Bad! Swift要求每个选项至少要有一条语句,否则就报错! default: grade = "差" // 每个switch必须有一个default选项 } println("grade = \(grade)")2) 支持梦寐以求的字符串匹配,以及用fallthrough进行贯穿:
let testChar: String = "e" switch testChar { case "a", "e", "i": fallthrough // 贯通,只能在switch中使用,不跳出继续执行下一个选项 case "o", "u": println("\(testChar) is a vowel") default: println("\(testChar) is not a vowel") // fallthrough // Bad! default中不能使用,否则会报错! }3) 也可以匹配浮点数,并且精度极高:
var x = 17.9 * 17.9 * 17.9 * 17.9 var y = sqrt(sqrt(x)) switch y { case 17.9: println("haha") default: println("suck") } // 输出haha,可见switch的浮点数匹配精度极高 // 内部应该使用了fabs < EPS的模型4) 离散范围匹配:
let score = 80 var grade: String switch score { case 90...100: grade = "优秀" case 80..<91: grade = "良好" case 60..<80: grade = "中等" default: grade = "差" }注意!是匹配离散范围,不能匹配浮点数!
5) 超级牛逼的元组匹配,并且可以用let/var获取匹配的值进行利用:
var tup = (1111, 1111, 1111) switch tup { case (7, 9, 2): println("严格匹配(7, 9, 2)") case (_, 8, 3): println("只关心后两个分量是8和3,第一个分量不关心") case (1...3, 5..<7, _): println("第一个分量范围必须是1到3,第二个分量范围必须是5到6,最后一个分量不关心") case (3, 3, 9), (_, 20..<39, 33...22): // 如果发生歧义(两种情况都能匹配),则按照case的选候顺序! println("元组也能匹配多种情况") case (9, let x, 9): // 要求第一个和最后一个分量必须是9,但是第二个分量又是需要用到的(并不是无所谓) // 此时使用let或者var取它的值并在case选项中利用该值,如果利用两个则可以(9, let x, let y) println("第一个和最后一个分量都是9,第二个分量的值是x: \(x)") case var (x, y, z): // 所有分量都用到就直接用let或var分解整个元组,但是这种情况一般很少遇到 println("分解元组:\((x, y, z))") default: println("nothing!") }6) 利用where子句达到SQL的WHERE语句的功能,轻松实现连续值的匹配:
var tup = ( 3.2, 7, 2.1 ) switch tup { case (let x, let y, 2.1) where x > 1.0 && y > 6: // where的使用和SQL类似 // where子句中判断的内容需要先使用let/var获取才行 println("haha") case (let x, 7, 3) where x > 3.2, (23.23, let y, 322.1) where y < 7: println("Wrong") // Bad! 不能同时使用一个以上的wherer子句 default: println("nothing") }单值当然也行,这也是匹配连续范围浮点数的一个典型例子:
var x = 3.2 switch x { case let x where 1.5 < x && x < 7.7: println(x) default: println("nothing!") }
4. while和do...while:
用法和C语言一样,注意所有条件判断必须是布尔类型的
var i: Int i = 0 while i < 10 { i++ } i = 0 do { i++ } while i < 10
5. for:
1) 普通for循环:基本和C语言的for循环保持高度的一致性,格式时for 初始化; 终止条件判断; 增量迭代 { ... },其中三个部分的任意一个部分都可以为空
// 定义初始化计数变量部分需要var,也支持,分隔多个 // var定义的是for循环内部的局部变量 // 和for...in不同的是,for...in不需要使用var而for需要 for var i = 0, j = 0; i < 10; i++, j++ { println("i = \(i), j = \(j)") } // for var k = 9, var i = 0; i < 10; i++ // 但是不能重复使用var var j = 0; for let i = 0; j < 10; j++ // 当然也可以使用let,但是let和var只能出现一次 { // 当然也可以使用for外面的作用域更大的变量作为计数变量,这里j就是一个例子 println("haha") } for var k = 0; k < 10; // 任意一个部分都可以是空 { k++ } for ; ; // 死循环的写法 { }
2) for...in:最主要用于迭代集合中的元素,之前已经出现过好多次了,和python的for迭代保持高度的一致性,所以Swift是一门综合的语言
其最大的优势就是迭代集合中的元素(大大简化代码),在其余情况下可能还是只能求助于传统for循环,凡是用for...in能办到的传统for循环一定能办到
// 迭代数组 let num = [1, 2, 3, 4, 5, 6, 7, 8, 9] for var i = 0; i < countElements(num); i++ // 传统for循环 { println(num[i]) } for elem in num // 使用for...in明显更简便 { println(elem) } // 迭代字典 let dic = ["haha": 1, "hihi": 2, "hoho": 3] for (name, id) in dic { println("name = \(name), id = \(id)") } for (_, id) in dic // 或者只关心一个量而忽略另一个量 { println(id) } // 区间迭代 for i in 1...3 { println(i) }
注意!for后面定义的变量是for循环的内部变量,作用范围仅限于for循环,过了for循环该变量就消失不可见了(即在for外面不能使用了)
3) 特殊用法:使用for...in的区间循环进行计数,有时根本不需要利用计数变量,而仅仅将其作为一种单纯的技术工具,这是就可以使用_来省略迭代变量,以下程序用来计算2的n次方
var n = 10 var base = 2 var ans = 1 for _ in 1...n // 只关心循环多少次而不关心当前循环到哪儿 { ans *= base } // 计算2的n次方4) 枚举字符串中的字符:字符串其实也是一种集合,因此也可以使用for...in迭代其中的字符
for char in "hello" { print("<\(char)>") } // <h><e><l><l><o>!!!注意!for...in中定义的迭代量都是常量类型的,即Swift自动将其定义为let型的,因此不得在循环中改变该值,否则会报错!
6. break、continue:
1) 用法跟C语言一模一样,用于循环语句内部的跳转,并且支持标签跳转来连跳多层循环,就连标签的定义也和C语言一模一样(break和continue的跳转标签只能定义在循环语句的开头位置!)
label: for i in 1...100 { for j in 1...100 { println("i = \(i), j = \(j)") if j == 10 { break label } } }2) break可以用在switch中,但是continue不能用在switch中,但是switch中每个选项的最后Swift都会默认添加一个隐式的break,当然自己强行加break也不会报错,效果就和Swift默认隐式添加break一样,一般用于选项中的条件判断:
var tup = (1, 2, 3) switch tup { case (3, 7, 9): println((3, 7, 9)) break // 加跟没加都一样 case (let x, 2, 3): if (x == 2) { break } else { fallthrough } case (1, 2, 3): println("命中") default: println("nothing!") } // 命中