由于可选项的内容可能为 nil, 而一旦为 nil 则不允许参与运算;
因此在实际开发中,经常需要判断可选项的内容是否为 nil;
如果单纯使用 if,会让代码嵌套层次很深,让代码不宜阅读和维护,为了解决这一问题,苹果提供了以下三种方式:
1> ?? 运算符用于判断 变量/常量 的数值是否是 nil ,如果是则使用后面的值替代;在Swift开发中, ?? 能够简化代码的编写。
2> if let/var
3> guard let/var else
guard let/var else:
1>guard let/var else 是与 if let/var 相反的语法,Swift2.0推出的;
2>在程序编写时,条件检测之后的代码相对是比较复杂的,使用 guard 的好处:能够判断每一个值;在真正的代码逻辑部分,省略了一层嵌套。
3>好处:代码的执行效率越高,嵌套的层次越少越好。
控制流是基本的逻辑分支结构,
可选项的三种判断方式:
1> ??,替换 nil 值,但是优先级低;
2> if let/var,变量在{}内有效;
3> guard let else,变量在{}后仍有效。
Swift 可以对任意类型的值进行分支
一、if
1.条件不需要(),语句必须有 {}
2.Swift 中没有 C 语言中的 非0即真 概念,在逻辑判断时,必须显式的指明具体的判断条件 true/false
let x = 10
if x > 5 {
print("大于")
} else {
// Will never be executed
// 永远不会被执行 - 编译器编译的时候,会进行语法检查!
print("小于")
}
二、三目运算符
let x = 10
// 跟 OC 的三目运算符一样的
x > 5 ? print("大于") : print("小于”)
// 只处理”大于“的情况:'()'表示空执行
x > 5 ? print("大于") : ()
三、可选项的判断
// MARK - 可选项的判断
func controlFlow2(x: Int?, y: Int?) {
// 1.强行解包有风险
// print(x! + y!)
// 2.使用 if 判断:如果使用 if 判断可能会使代码很丑陋
if x != nil && y != nil {
print(x! + y!)
} else {
print("x 或者 y 为nil")
}
}
// 调用
controlFlow2(x: 10,y: 20)
// MARK - 可选项使用 ?? 的判断
func controlFlow3(x: Int?, y: Int?) {
/**
?? 是一个简单的三目
- 如果有值,使用值;如果没有值,使用 ?? 后面的值替代
*/
print((x ?? 0) + (y ?? 0))
let name: String? = "张三"
// ?? 操作符号的优先级'低',在使用的时候最好加上小括号包裹
print("Hello" + (name ?? "Anyone"))
// 打印结果:Hello张三
let name2: String? = nil
print("Hey" + (name2 ?? "嗯哼"))
// 打印结果:Hey嗯哼
}
四、if let/var
if let / var 连用语法,目的:判断值
func controlFlow4() {
let oName: String? = "张三"
let oAge: Int? = 10
if oName != nil && oAge != nil{
print(oName! + String(oAge!))
}
if let 连用,判断对象的值是否为 nil,在 {} 内一定有值,可以直接使用,不需要解包
if let name = oName,
let age = oAge {
// 进入分支之后,name 和 age 一定有值,不需要解包;
// name 和 age 的作用域仅在 {} 中
print(name + String(age))
// 打印结果:张三10
} else {
print("oName 或 oAge 为nil")
}
if var 连用,在 {} 内可以对值进行修改!
if var name = oName,
let age = oAge {
name = "李四"
print(name + String(age))
// 打印结果:李四10
} else {
print("oName 或 oAge 为nil")
}
}
五、guard 守卫/守护
guard 的语法是Swift 2.0 推出的!
如果用 if let/var 凭空多了一层分支,guard是降低分支层次的方法
func controlFlow5() {
// guard let 和 if let 刚好相反
let oName: String? = "张三"
let oAge: Int? = 10
// guard let 守护一定有值,如果没有直接返回
guard let name = oName,
let age = oAge else {
print("oName 或 oAge 为 nil")
return
}
// 代码执行至此,name 和 age 一定有值!不需要考虑解包问题。
// 通常判断是否有值之后,会做具体的逻辑实现,代码通常多!
print(name + String(age))
}
六、if let 和 guard let 的技巧
if let 的 name的作用域仅在if let后面 {} 内有效;
guard let 的 name的作用域在guard let {} 外也有效。
使用同名的变量接收值,在后续使用的都是非空值,不需要解包
好处:可以避免起名字的烦恼
func controlFlow6(name: String?,age: Int?) {
if let name = name,
let age = age {
// 非空的 name 和 age 仅在 {} 内有效!
print(name + String(age))
// 打印结果:李四18
}
guard let name = name,
let age = age else {
print("name 或者 age 为 nil")
return
}
print(name + String(age))
// 打印结果:李四18
}
七、switch
OC中的switch
1.分支值类型必须是 整数
2.每个语句都需要一个 break
3.如果要穿透,则省略需要穿透的 case 后面的 break
4.如果要定义局部变量,需要 {}
5.OC中 {} 可以限定变量的作用域!
因为程序的执行顺序是从上往下,如果不加 {} ,无法确定变量的作用域。
Swift中的switch
1. switch 可以对 任意类型的值 进行分支,不再局限于整数;
2. 一般不需要 break
3. 如果有多值,使用 ‘,’
4. 所有的分支至少需要一条指令,如果什么都不干,才使用 break
5. 每一个 case 后面必须有可以执行的语句
6. 要保证处理所有可能的情况,不然编译器直接报错,不处理的条件可以放在 default 分支中
7. 每一个 case 中定义的变量仅在当前 case 中有效,而OC中需要使用{}
func demo(num: String) {
switch num {
case "10","9":
print("Good")
case "8":
print("Not Good")
break
default:
print("Bad")
}
}
八、for循环
传统 for,在 Swift 3.0 被取消;
i++ / ++i 从 Swift 3.0 被取消,可以使用 i += 1;
// 变量 i 在 右开区间 [0,5) 循环
for i in 0..<5 {
print(i)
}
// 变量 i 在 闭区间 [0,5] 循环
for i in 0...5 {
print(i)
}
let r1 = 0..<5
print(r1)
// 打印结果:0..<5
let r2 = 0...5
print(r2)
// 打印结果:0...5
// 反序遍历
for i in (0...10).reversed() {
print(i)
}
注意:范围定义是一个固定的格式,一定要注意空格!Swift 对语法要求非常严,尤其是空格!