1、控制流
使用 if 和 switch 来进行条件操作,使用 for-in、for、while 和 do-while 来进行循环。包裹条件和循环变量括号可以省略,但是语句体的大括号是必须的。
注:在 if 语句中,条件必须是一个布尔表达式——像 if score { ... }这样的代码是错误的。
2、可选值和值缺失
有些变量的值是可选的。一个可选的值可能是一个具体的值或者是 nil,表示值缺失。在类型后面加一个问号来标记这个变量的值是可选的。
var optionalString:String? = "Hello"
optionalString == nil
var optionalName:String? = "Andy"
var greeting = "Hello !"
if let name = optionalName
{
greeting = "Hello, \(name)"
}
else
{
greeting = "name is a nil"
}
3、使用switch,支持任意类型的数据以及各种比较操作——不仅仅是整数以及测试相等
在 Swift 中,当匹配的 case 块中的代码执行完毕后,程序会终止 switch 语句,而不会继续执行下一个case块.
let vegetable = "red pepper"
var vegetableComment = ""
switch vegetable
{
case "celery":
vegetableComment = "Add some raisins and make ants on a log."
case "cucumber", "watercress":
vegetableComment = "That would make a good tea sandwich."
case let x where x.hasSuffix("pepper"):
vegetableComment = "Is it a spicy \(x)?”
default :
vegetableComment = "Everything tastes good in soup."
}
4、每一个 case 块都必须包含至少一条语句
下面这种写法是无效的,因为第一个case没有语句。
switch anotherCharacter {
case "a":
case "A":
println("The letter A”)
default:
println("Not the letter A")
}
必须修改成: case “a”, “A”:
5、case块可以是一个值范围
switch anotherCharacter {
case “1...3":
println(“range 1-3”)
case “4...9":
println(“range 4-9”)
default:
println("Not in range")
}
6、case块结合元组的使用
你可以使用元组在同一个 switch 语句中测试多个值。元组中的元素可以是值,也可以是范围。另外,使用下划线(_)来匹配所有可能的值。
下面的例子展示了如何使用一个(Int, Int)类型的元组来分类下图中的点(x, y):
let somePoint = (1, 2)
var str1:String
switch somePoint{
case (0, 0):
str1 = "(0, 0) is at the origin"
case (_, 0):
str1 = "(\(somePoint.0), 0) is on the x-axis"
case (0, _):
str1 = "(0, \(somePoint.1)) is on the y-axis"
case (-2...2, -2...2):
str1 = "(\(somePoint.0), \(somePoint.1)) is inside the box"
default:
str1 = "(\(somePoint.0), \(somePoint.1)) is outside of the box"
}
注:swift 允许多个 case 匹配同一个值。实际上,在这个例子中,点(0, 0)可以匹配所有四个 case。但是,如果存在多个匹配,那么只会执行第一个被匹配到的 case 块。
7、case块的值绑定
case允许将匹配到的值绑定到一个临时的常量或变量上面,这些常量或变量就可以在该case块中使用。
let anthorPoint = (2, 0)
var str2:String
switch anthorPoint{
case (let x, 0):
str2 = "on the x-axis with an x value of \(x)"
case (0, let y):
str2 = "on the y-axis with a y value of \(y)"
case let (x, y):
str2 = "somewhere else at (\(x), \(y))"
}
8、case块的 where 语句
我们可以在case里面使用 where 语句来判断额外的条件。
let yetAnotherPoint = (1, -1)
var str3:String
switch yetAnotherPoint{
case let (x, y) where x == y:
str3 = "(\(x), \(y)) is on the line x == y"
case let (x, y) where x == -y:
str3 = "(\(x), \(y)) is on the line x == -y"
case let (x, y):
str3 = "(\(x), \(y)) is just some arbitrary point"
}
9、for-in循环
for index in 1...5 {
println("\(index) times 5 is \(index * 5)")
}
注:如果你不需要知道范围内每一项的值,你可以使用下划线(_)替代变量名来忽略对值的访问。
for _ in 1...5{
println("andy")
}
10、for-in 来遍历字典,需要两个变量来表示每个键值对
let interest_numbers = [
"Prime": [2, 3, 5, 7, 11, 13],
"Fibonacci": [1, 1, 2, 3, 5, 8],
"Square": [1, 4, 9, 16, 25],
]
var largest = 0
var largest_type:String? = ""
for (type, numbers) in interest_numbers
{
for number in numbers
{
if number > largest
{
largest = number
largest_type = type
}
}
}
"The largest number is \(largest), the type is \(largest_type)"
11、for循环
for var index = 0; index < 3; ++index {
...
}
注:Swift 不需要使用圆括号将“initialization; condition; increment”包括起来
12、使用while 和 do-while
var n = 2
while n < 100
{
n *= 2
}
var m = 2
do
{
m *= 2
}
while m < 100
13、使用循环范围标识符 ..<
你可以在循环中使用 ..< 来表示范围也可以使用传统的写法,两者是等价的:
var first_loop = 0
for i in 0 ..< 5
{
first_loop += i
}
注:使用 ..< 创建的范围不包含上界,如果想包含的话需要使用 ...
==== 两者等同 ====
var second_loop = 0
for var i=0; i<5; ++i
{
second_loop += i
}
14、控制转移语句
- continue:它告诉循环体停止本次循环,开始下次循环。
- break:结束整个控制流的执行。
- fallthrough:在Swift中,
只要第一个匹配到的 case 分支完成了它需要执行的语句,整个 switch 代码块完成了它的执行,如果你想执行下面的case,就需要加上fallthrough来指定继续执行下个case。
- return
注:fallthrough 关键字不会检查它下一个将会落入执行的 case 中的匹配条件。fallthrough 简单地使代码执行继续连接到下一个 case 中的执行代码。
15、循环体标签(labeled Statements)
在Swift控制语句中,你可以嵌套循环体,但是当我们使用 break 或 continue 的时候,我们必须要知道针对哪个循环体,所以就出现了循环体标签。
labelname: while condition {
...
}
上面只需要在一个循环体前面加上 labelname ,后面加上 : 就完成了循环体标签。
16、小游戏代码,页数103
let finalSquare = 25
var board = Array<Int>(count: finalSquare + 1, repeatedValue: 0)
board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
var square = 0
var diceRoll = 0
gameLoop: while square != finalSquare{
if ++diceRoll == 7 {
diceRoll = 1
}
switch square + diceRoll{
case finalSquare :
// diceRoll will move us to the final square, so the game is over
break gameLoop
case let currentSquare where currentSquare > finalSquare :
// diceRoll will move us beyond the final square, so roll again
continue gameLoop
default :
// this is a valid move, so find out its effect
square += diceRoll
square += board[square]
}
}