For循环
for循环有两种形式,一种是for in 可以方便的变量数组等集合类型,另一张是与c语言类型的基本for循环。
for in
let numberOfLegs = ["spider": 8,"ant": 6,"cat": 4] for (animalName,legCount) in numberOfLegs { print("\(animalName)s have \(legCount) legs") } // spiders have 8 legs // ants have 6 legs // cats have 4 legs
条件递增
for var index = 0; index < 3; ++index { print("index is \(index)") } // index is 0 // index is 1 // index is 2
在初始化表达式中声明的常量和变量(比如var index = 0)只在for循环的生命周期里有效。
如果想在循环结束后访问index的值,你必须要在循环生命周期开始前声明index。
while循环
while也包括两种,while循环和repeat while循环(repeat while 就是其他语言的 do while)
while
var square = 0 var diceRoll = 0 while square < finalSquare { // 掷骰子 if ++diceRoll == 7 { diceRoll = 1 } // 根据点数移动 square += diceRoll if square < board.count { // 如果玩家还在棋盘上,顺着梯子爬上去或者顺着蛇滑下去 square += board[square] } } print("Game over!")
repeat while
repeat { // 顺着梯子爬上去或者顺着蛇滑下去 square += board[square] // 掷骰子 if ++diceRoll == 7 { diceRoll = 1 } // 根据点数移动 square += diceRoll } while square < finalSquare print("Game over!")
代码摘自 the swift programing language 2
if语句
let temperatureInFahrenheit = 90 if temperatureInFahrenheit <= 32 { print("It's very cold. Consider wearing a scarf.") } else if temperatureInFahrenheit >= 86 { print("It's really warm. Don't forget to wear sunscreen.") } else { print("It's not that cold. Wear a t-shirt.") } // 输出 "It's really warm. Don't forget to wear sunscreen."
switch语句
let someCharacter: Character = "e" switch someCharacter { case "a","e","i","o","u": print("\(someCharacter) is a vowel") case "b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z": print("\(someCharacter) is a consonant") default: print("\(someCharacter) is not a vowel or a consonant") } // 输出 "e is a vowel"
与 C 语言和 Objective-C 中的switch语句不同,在 Swift 中,当匹配的 case 分支中的代码执行完毕后,程序会终止switch语句,而不会继续执行下一个 case 分支。
这也就是说,不需要在 case 分支中显式地使用break语句。这使得switch语句更安全、更易用,也避免了因忘记写break语句而产生的错误。
区间匹配
let count = 3_000_000_000_000 let countedThings = "stars in the Milky Way" var naturalCount: String switch count { case 0: naturalCount = "no" case 1...3: naturalCount = "a few" case 4...9: naturalCount = "several" case 10...99: naturalCount = "tens of" case 100...999: naturalCount = "hundreds of" case 1000...999_999: naturalCount = "thousands of" default: naturalCount = "millions and millions of" } print("There are \(naturalCount) \(countedThings).") // 输出 "There are millions and millions of stars in the Milky Way."
元组匹配
你可以使用元组在同一个switch语句中测试多个值。
元组中的元素可以是值,也可以是区间。另外,使用下划线(_)来匹配所有可能的值。
let somePoint = (1,1) switch somePoint { case (0,0): print("(0,0) is at the origin") case (_,0): print("(\(somePoint.0),0) is on the x-axis") case (0,_): print("(0,\(somePoint.1)) is on the y-axis") case (-2...2,-2...2): print("(\(somePoint.0),\(somePoint.1)) is inside the Box") default: print("(\(somePoint.0),\(somePoint.1)) is outside of the Box") } // 输出 "(1,1) is inside the Box"
值绑定
case 分支的模式允许将匹配的值绑定到一个临时的常量或变量.
这些常量或变量在该 case 分支里就可以被引用了——这种行为被称为值绑定(value binding)。
let anotherPoint = (2,0) switch anotherPoint { case (let x,0): print("on the x-axis with an x value of \(x)") case (0,let y): print("on the y-axis with a y value of \(y)") case let (x,y): print("somewhere else at (\(x),\(y))") } // 输出 "on the x-axis with an x value of 2"
where语句
let yetAnotherPoint = (1,-1) switch yetAnotherPoint { case let (x,y) where x == y: print("(\(x),\(y)) is on the line x == y") case let (x,y) where x == -y: print("(\(x),\(y)) is on the line x == -y") case let (x,y): print("\(x),\(y)) is just some arbitrary point") } // 输出 "(1,-1) is on the line x == -y"
转移控制语句
fallthrough
如果你确实需要 C 风格的贯穿(fallthrough)的特性,你可以在每个需要该特性的 case 分支中使用fallthrough关键字。
下面的例子使用fallthrough来创建一个数字的描述语句。
let integerToDescribe = 5 var description = "The number \(integerToDescribe) is" switch integerToDescribe { case 2,3,5,7,11,13,17,19: description += " a prime number,and also" fallthrough default: description += " an integer." } print(description) // 输出 "The number 5 is a prime number,and also an integer."
带标签的语句
跟c语言的goto很像
gameLoop: while square != finalSquare { if ++diceRoll == 7 { diceRoll = 1 } switch square + diceRoll { case finalSquare: // 到达最后一个方块,游戏结束 break gameLoop case let newSquare where newSquare > finalSquare: // 超出最后一个方块,再掷一次骰子 continue gameLoop default: // 本次移动有效 square += diceRoll square += board[square] } } print("Game over!")
因为在这个游戏中,只有一个循环体,所以continue语句会影响到哪个循环体是没有歧义的。
然而,continue语句使用gameLoop标签也是没有危害的。
这样做符合标签的使用规则,同时参照旁边的break gameLoop,能够使游戏的逻辑更加清晰和易于理解。
最后还有 guard语句,看起来很像断言。