//: Playground - noun: a place where people can play
import UIKit
// # For-in 循环
// 遍历一个序列Sequence,比如左闭的Range,Array,Set,String,Dictionary
// 那个用于遍历的常量,在每次遍历循环开始的时候被隐式声明,每个循环结束了,它就不在了
// trick: 用stride(from:to:/through:by:)跳过
for a in stride(from: 0, to: 20, by: 5) {
print(a)
}
for a in stride(from: 0.0, through: 1.0, by: 0.2) {
print(a)
}
// # While 循环
// 蛇与梯子游戏
// 最大格数
let finalSquare = 25
// 初始化
var board = [Int](repeatElement(0, count: finalSquare + 1))
// 安置蛇与梯子
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
while square < finalSquare {
// roll the dice
diceRoll += 1
if diceRoll == 7 { diceRoll = 1 }
// move by the rolled amount
square += diceRoll
print(square)
if square < board.count {
// if we're still on the board, move up or down for a snake or a ladder
square += board[square]
} // trick: 这是一种比较好的检查下表越界的方式
}
print("Game over!")
// Repeat-while 语句
// # 条件语句
// switch
// trick: case后用逗号隔开可以符合多个条件
// trick: 区间匹配
switch 5 {
case ...0:
print("")
default:
print("f")
}
let somePoint = (1, 1) // 感觉元组有点像是广义上的坐标
switch somePoint {
case (0, 0): // 一旦匹配,会忽略后面的case
print("(0, 0) is at the origin")
case (_, 0): // _表明匹配所有可能的值
print("(\(somePoint.0), 0) is on the x-axis")
case (0, let y): // 值绑定
print("(0, \(y)) is on the y-axis")
case (-2...2, -2...2):
print("(\(somePoint.0), \(somePoint.1)) is inside the box")
case let (x, y):
print("(\(x), \(y)) is outside of the box")
}
// trick: 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): // 已经匹配到了所有的情况,所以不需要default
print("(\(x), \(y)) is just some arbitrary point")
}
// 复合情况同样可以包含值绑定。所有复合情况的模式都必须包含相同的值绑定集合,并且复合情况中的每一个绑定都得有相同的类型格式。这才能确保无论复合情况的哪部分匹配了,接下来的函数体中的代码都能访问到绑定的值并且值的类型也都相同。
let stillAnotherPoint = (9, 0)
switch stillAnotherPoint {
case (let distance, 0), (0, let distance): // 相同的绑定名称
print("On an axis, \(distance) from the origin")
default:
print("Not on an axis")
}
// 一般情况值绑定
var b = 2
switch b {
case let a where a > b:
print(a)
case let b: // 相当于default
print(b)
print("")
}
// # 控制转移语句***
// continue 语句告诉循环停止正在做的事情并且再次从头开始循环的下一次遍历。
// break 语句会立即结束整个控制流语句.在switch中,可以把break作为整个函数体来无视该条件(因为Swift的switch必须要穷尽,而有时候某些范围没啥用),比如default中
// 使用fallthrough跟着执行一下个case或default的代码块,而不执行条件检查
// trick: 在小循环(or switch)里面中断大循环,让结构更加清晰
bigLoop: for i in 1...10 {
switch i {
case 1, 2, 3:
continue bigLoop
case 8:
print("terminate")
break bigLoop
default:
print(i)
}
}
// # 提前退出
// guard 语句来要求一个条件必须是真才能执行 guard 之后的语句。与 if 语句不同, guard 语句总是有一个 else 分句, else 分句里的代码会在条件不为真的时候执行。guard语句一般用于提前退出
// guard let 语句只有else 分句,没有为真的语句
func greet(_ person: [String: String]) {
guard let name = person["name"] else { return } // trick:没有名字直接函数结束
print("Hello \(name)!") // 在外面依然可以使用name
guard let location = person["location"] else {
print("I hope the weather is nice near you.") // 没有地点就泛泛而谈
return
}
print("I hope the weather is nice in \(location)") // 有地点
}
greet(["name": "John"])
greet(["name": "Jane", "location": "Cupertino"])
// # 检查API的可用性
if #available(iOS 11, *) {
// 只有当系统不低于11时,才执行这里的代码
} else {
// 执行旧平台代码
}
网友评论