一个 C++ 程序员眼中的 Swift(三)
On 2014-12-03 23:22:15 By Soli一个 C++ 程序员眼中的 Swift(三)
接下来的内容就更有趣了,方便的for-in、强大的switch、 穿越的break等等。每一个都戳到了 C++ 程序员的痛处或痒处。
- for-in- 现在大多数语言都已支持 - for-in语句了。C/C++ 还在固守成规。- Swift 的 - for-in语句与它的区间运算符简直是绝配,写个循环如此简单:- var sum = 0 for i in 0..<10 { sum += i }- 迭代数组也极其方便: - let names = ["xiaoming", "xiaolan", "xiaohong"] for i in 0..<names.count { println("\(names[i])") }- 迭代数组何必需要下标? - let names = ["xiaoming", "xiaolan", "xiaohong"] for name in names { println("\(name") }- 往下看前先默念一遍 C++ 中如何迭代 - std::map的。然后再看 Swift 是怎么做的:- let scores = ["xiaoming":98, "xiaolan":89, "xiaohong":99] for (name, score) in scores { println("\(names) got \(score)") }
- 增强的 - switch- 不再有漏写 - break的烦恼。Swift 的- switch中每个- case都是默认- break的,无需在最后写- break。- 但在 C/C++ 中,有时我们是故意不写 - break的。Swift 为了支持这一特性,增加了- fallthrough语句。- 虽然增加了新的语句,但这更符合实际情况。在大多数情况下我们想要的是 - break,而极少数情况下才需要- fallthrough。而默认值应该是照顾大多数情况的。所以,Swift 中是默认- break而需要显式写- fallthrougn,而 C/C++ 中却是默认- fallthrough而需要显式写- break。- 下面是个例子: - let skills = 2 var description = "You are a " switch skills { case 2: description += "senior " fallthrough case 1: description += "expert" default: description += "good guy" } println(description)
- Swift 要求 - switch中的- case必须是完备的,即列举所有的情况。当然,可以使用- default来覆盖那些我们不关心的情况。- Swift 还要求每个 - case下必须含有有效的语句(注释不算)。所以,如果你想忽略某个(些)- case,你需要显式的写个- break。
- 每个 - case可以写多个条件:- switch result { case "true", "True": println("correct") case "false", "False": println("wrong") default: println("invalid") }
- case里的条件不只是一个或多个的值,还可以是区间:- switch temperature { case -40 ... -10: println("frigid") case -10 ... 5: println("cold") case 5 ... 20: println("cool") case 20 ... 28: println("warm") case 28 ... 40: println("hot") default: println("not for human beings") }
- 还可以是元组: - switch (strength, magic) { case (0, 0): println("die") case (0, _): // 下划线表示该项可为任意值。 println("revive") case (80...100, 80...100) println("attack") case (0...30, _): println("escape") default: println("defense") }- 可以看到,各个条件是可以重叠甚至相同的。Swift 只执行第一个匹配到的条件下的语句。 
- 值绑定 - 有时你需要在 - case里的代码段里使用- case所匹配到的值。这时可能就会用到值绑定。比如:- let point = (0, 3) switch point { case (let row, 0): println("rown number of \(row)") case (0, let col): println("headline of \(col)") case let (row, col): println("data of (\(row), \(col))") }- 当然,也可以用 - var声明变量来进行值绑定。- 这个特性除了方便之外,似乎没有什么用。因为我们可以通过 - point这个常量来引用我们需要的值。比如:- let point = (0, 3) switch point { case (_, 0): println("rown number of \(point.0)") case (0, _): println("headline of \(point.1)") default: println("data of (\(point.0), \(point.1))") }
- 用 - where给- case加上条件判断。这让- switch更像一系列- if...else了。- let point = (3,3) switch point { case (_, _) where point.0 > 0 && point.1 > 0: println("point is on the first quadrant") case let (x, y) where x > 0 && y < 0: // 用了值绑定,是不是方便多了。 println("point is on the forth quadrant") case let (x, y) where x < 0 && y > 0: println("point is on the second quadrant") case let (x, y) where x < 0 && y < 0: println("point is on the third quadrant") default: println("point is on the axes") }
 
- 带标签的语句 - 在嵌套循环中,有时我们想直接跳出到最外层循环。另外,在嵌套的 - switch里,或循环和- switch混合嵌套的情况下,同样有这种需求。- 在 C/C++ 中可以使用 - goto语句来实现。有时这也不失为一种优雅的办法。在很多教材或文章中,甚至在很多老师和前辈的口中,- goto语句都被妖魔化了。为了避免使用- goto,宁可增加很多标志变量再绕几个弯儿来实现一句- goto就可以实现的逻辑。即使有充分的理由在代码中使用了- goto,心理上也承受着会被别人嘲讽的压力。- 在 Swift 中,你完全可以抛掉这些心理负担了。因为只需在 - for、- while或- switch等语句前加个标签,你就可以随心所欲的- break或- continue指定的控制流了。- fl: for i in 0...20 { sl: switch i { case 0: fallthrough case 1: break sl default: for j in 2..<i { switch i % j { case 0: continue fl default: break } } println("\(i)") } }
- 未完待续 
 Except where otherwise noted, content on this site is licensed under a
		
			Creative Commons Attribution 4.0 International license
		
		.
		
		Except where otherwise noted, content on this site is licensed under a
		
			Creative Commons Attribution 4.0 International license
		
		.