流程控制
结构化的程序设计,不管是面向过程,还是面向对象,都离不开三种基本结构。
即:顺序结构、选择结构、循环结构。
顺序执行自然不用多说。
选择结构即基于特定的条件执行不同的代码分支,如 if , guard 和 switch 等条件语句。
循环结构主要是For-in,While 和 Repeat-While 语句。
If conditionals
你可以使用 if 语句来判定简单的条件,比如少量的可能性。 switch 语句则适合更复杂的条件,比如多个可能的组合,并可以进行模式匹配。
简单用法
// IF
// 最简单的用法,条件表达式不需要小括号,大括号不能省略
let age = 20
if age > 18 {
print("成年了")
}
let score = 61
if score>60 {
print("及格")
} else {
print("不及格")
}
If -let 可选绑定
注意:当碰到可选类型(Optionals)时,if 语句就会变得有些不可控了!
let score:Int? = 61 // or: let score: Int? = nil
if score>60 {
print("score is: \(score + 0)")
} else {
print("不及格")
}
根据Xcode的提示,我们有两种方式进行修复:
// 修改方式1:
// 使用 ?? 操作符,但是 ?? 必须提供一个默认值! 恶心
let score:Int? = 61
if score ?? 0>60 {
print("score is: \(score ?? 0 + 0)")
} else {
print("不及格")
}
// 输出 61
// 修改方式2:
// 使用!断言,我确信没有问题的,可选类型可以unwrapped 为 Int类型!
// 虽然我确信,但是程序崩了我不负责! ?
let score:Int? = 61
if score!>60 {
print("score is: \(score!+0)")
} else {
print("不及格")
}
// 修改方式3
let score:Int? = 61
if score != nil {
// 即使我们已经判空了,这里还是可选的类型,不能直接运算
if score! > 60 {
print("及格了")
}else {
print("不格了")
}
}else {
print("什么都没有")
}
以上方式都很恶心啊,试试 if let 吧
if-let可以检查一个Optional类型所持有的值,使用 if -let 判断后不需要解包
let score:Int? = 61
if let newScore = score {
if newScore>60 {
print("及格了:\(newScore) 分")
}else {
print("不及格")
}
}
// 输出:及格了:61 分
newScore 的作用域仅在 {} 中,当然Swift 推荐我们可以重用score的命名,即:
let score:Int? = 61
if let score = score {
if score>60 {
print("及格了:\(score) 分")
}else {
print("不及格")
}
}
如果你觉得上述写法还不够爽,看看下面的写法:
let score:Int? = 61
if let score=score,score>60 {
print("及格了\(score)")
}else {
print("不及格")
}
参考文档: https://github.com/apple/swift-evolution/blob/master/proposals/0099-conditionclauses.md
Swift3 之前的写法是: if let score=score where score>60
guard let
guard let和 if let 刚好相反,guard let 守护一定有值。如果没有,直接返回。
func checkUsername(username: String) {
guard username=="admin" else {
print("你不是管理员,没有权限")
return
}
print("欢迎你,管理员:\(username)")
}
checkUsername(username: "Jack Ma") //不是管理员,没有权限
checkUsername(username: "admin") //欢迎你,管理员:admin
如果是可选类型能,使用guard let 即可:
func checkUsername(username: String?) {
guard let username = username, username=="admin" else {
print("你不是管理员,没有权限")
return
}
print("欢迎你,管理员:\(username)")
// 可以随心所欲的使用 username 了
}
checkUsername(username: "Jack Ma") //不是管理员,没有权限
checkUsername(username: "admin") //欢迎你,管理员:admin
checkUsername(username: nil) //你不是管理员,没有权限
guard let 的用法必须掌握,真实项目中,用的非常多的。
switch statements
基础用法
let name = "admin"
switch name {
case "Jack":
print("Jack")
case "admin":
print("Admin")
default:
print("Not Jack,not Admin")
}
注意:switch 语句中不需要*break,并且switch 会终止执行
如果如果你想在 switch 中让 case 之后的语句会按顺序继续运行,则需要使用 fallthrough 语句。
let value = "1"
switch(value) {
case "1":
print("go")
fallthrough
case "2":
print("go")
fallthrough
default:
print("go")
}
// 输出3个 go go go
// 是不是感觉 fallthrough 完全没有什么卵用
高级用法
文章开头我们提到,Swift 适合复杂的条件判断,看看下面的示例:
// 区间匹配
let score = 60
switch score {
case 0:
print("Zero,傻瓜")
case 1..<60:
print("不及格")
case 60..<70:
print("及格")
case 70..<90:
print("良好")
case 90...100:
print("优秀")
default:
print("翻天了")
}
// 当 score 为0, 输出 Zero,傻瓜
// 当 score 为 1- 59 , 输出 不及格
// 当 score 为 60- 69 , 输出 及格
// 当 score 为 101 输出 及格 翻天了
// 匹配元祖
//可以使用元组来在一个 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")
}
// prints "(1, 1) is inside the box"
// 匹配enum
enum DireactionModel {
case East,South, West,North
}
let direction = DireactionModel.East
switch direction {
case .East:
print("东方")
case .South:
print("南方")
case .West:
print("西方")
case .North:
print("北方")
}
// 输出:东方
// 关于Swift 的用法还有很多,比例和where 一起使用,可以和class结合使用,等等
循环Loops
For-in 循环
使用 for-in 循环来遍历序列,比如一个范围的数字,数组中的元素或者字符串中的字符。
// 数字区间
for i in 0...2 {
print(i)
}
// Both print:
// 0
// 1
// 2
// 遍历数组
let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names {
print("Hello, \(name)!")
}
// Hello, Anna!
// Hello, Alex!
// Hello, Brian!
// Hello, Jack!
// 遍历字典
let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
for (animalName, legCount) in numberOfLegs {
print("\(animalName)s have \(legCount) legs")
}
// ants have 6 legs
// cats have 4 legs
// spiders have 8 legs
// enumerated() Returns a sequence of pairs (n, x)
// enumerated()返回一个新的序列,包含了初始序列里的所有元素,以及与元素相对应的编号
for (n, c) in "Swift".enumerated() {
print("\(n): '\(c)'")
}
// Prints "0: 'S'"
// Prints "1: 'w'"
// Prints "2: 'i'"
// Prints "3: 'f'"
// Prints "4: 't'"
while
var num = 1
while num < 3 {
print("num:\(num)")
num += 1
}
//num:1
//num:2
Repeat-while loop
var i: Int = 0
repeat {
print(i)
i += 1
} while i < 3
Repeat-while 会比 do-while 更富语义吗?
where子句
let students = ["Jack":13,"Lucy":59,"Jim":88,"Tom":90]
for (name,score) in students where score<60 {
print("\(name) 不及格")
}
//Lucy 不及格
//Jack 不及格
forEach
// 定义
/*
Calls the given closure on each element in the sequence
in the same order as a for-in loop.
*/
func forEach(_ body: (Int) throws -> Void) rethrows
// 可见,forEach 参数是一个闭包。将序列的元素作为参数
let arr = [1,2,3,4]
arr.forEach{
print($0)
}
// 等同于
arr.forEach {
num in
print(num)
}
好了,关于Swift中的流程控制就介绍到这里了,是不是既简单又不简单。