简介
- 逻辑分支即常用的
if
、switch
、三目这些通过逻辑判断后决定后面执行什么的逻辑语句,通过分支语句可以控制程序的执行方向和流程。 - Swift 中逻辑分支的特点
- Swift 中没有 C 语言中
非零即真
的概念; - 所有判断条件必须显式的指明具体的判断条件
true
或者false
。
- Swift 中没有 C 语言中
if逻辑分支
-
简单体验
func demo() { let a = 10 if a >= 10 { print("OK") } }
以上代码是一段正确的可执行代码,在执行过程中程序会判断 a 是否大于或者等于 10,如果满足判断条件就执行
{}
里面的语句,否则将不执行。 -
Swift中 if 语句的特点
- 判断语句不需要
()
; - 执行语句必须要用
{}
,即使后面只有一句代码也不允许省略。
- 判断语句不需要
-
可选项的逻辑判断
-
在可选项的解包过程中如果我们使用
!
来强行解包,会出现可选值为空的风险,例如以下代码会出现的问题:override func viewDidLoad() { super.viewDidLoad() demo(x: 10, y: nil) } func demo(x : Int?, y : Int?) { print(x! + y!) }
当函数 demo 中传入一个
nil
值的时候会出现运行错误,这个错误我们会经常碰到,所以在选择解包方法的时候就需要作出有效的判断,避免出现这种错误,以下代码为修正版:override func viewDidLoad() { super.viewDidLoad() demo(x: 10, y: nil) } func demo(x : Int?, y : Int?) { if x != nil && y != nil { print(x! + y!) } else { print("x 或者 y 的值为 nil") } }
以上代码解决了可选值为空的风险,但是会造成新的问题。如果可选值的赋值足够复杂的情况下那么我们写出的代码就会很丑陋,例如王巍在自己书中的一段反面教材:
从上面图片中可以看出在解包一个复杂性json
字符串的时候出现了大量的if
语句和大量的花括号,使代码显得冗余繁杂,看了开头就不想看结尾的感觉,这样的代码被人称为“不是给人读的代码”。在Swift中提供了一个简单的三目运算符可以大大提高开发效率也可以大大提高代码的可读性,下面上代码演示:override func viewDidLoad() { super.viewDidLoad() demo() } func demo(a : Int?, b : Int) { print((a ?? 0) + (b ?? 0)) }
上面代码中使用一个
??
运算符解决了代码冗余的问题,而且可读性也大大提高。这个??
是一个简单的三目,它的作用是判断??
运算符前面的可选值(如果有值使用值,如果没有值使用运算符后面的值作为替代运算)。
值得注意的是,??
运算符的优先级比较低,所以在使用的时候要注意优先级。
-
if let / var 连用语法
if let
和 if var
连用不是单纯的 if
语句,是赋值的同时判断对象是否为 nil
,判断完之后{}
内一定有值,可以直接使用不需要解包。如果判断对象为nil
,不执行 {}
里的代码直接向下执行。以下代码演示:
- if let
override func viewDidLoad() { super.viewDidLoad() demo() } func demo() { let memberName : String? = “张三” let memberAge : Int? = 18 if let oName = memberName, oAge = memberAge { print(oName + "今年" + String(oAge) + "岁了") } }
输出到打印台的结果:
- if var
输出到打印台的结果:override func viewDidLoad() { super.viewDidLoad() demo() } func demo() { let memberName : String? = "张三" let memberAge : Ing? = 18 if var oName = memberName, let oAge = memberAge { oName = "李四" print(oName + "今年" + String(oAge) + "岁了") } }
通过输出结果可以看到,let var
的接收值在{}
中是允许修改的,这样我们在开发中就可以灵活使用。
guard let 守护语句
Swift2.0的时候推出了guard let
守护语句,guard let
和 if let
的功能正好相反。如果被guard let
守护的对象值为 nil
就执行 {}
里的代码,如果对象值不为 nil
就继续向下执行。以下代码演示:
override func viewDidLoad() {
super.viewDidLoad()
demo()
}
func demo() {
let memberName = "张三"
let memberAge = 18
guard let oName = memberName,
let oAge = memberAge else {
print("姓名或者年龄为nil")
return
}
// 代码执行到这,oName 和 oAge 一定有值
print(oName + "今年" + String(oAge) + "岁了")
}
打印台输出结果:
刚刚接触
guard let
的朋友也许会觉得奇怪,苹果为什么会设计这样一种奇葩的语法格式。之前我接触过的所有开发语言中都没有这样的先例,刚学习Swift的时候我也觉得奇怪,但用熟练了之后发现这样的设计方式真的很人性化,并且能很有效的缩短阅读代码的时间。通常在做完判断是否有值之后,会做具体的逻辑判断,具体的逻辑通常代码量会很大,如果用
if let
就会凭空多出一层分支,guard let
可以有效的减少分支量。
三目
- 简单体验
let a = 10 a > 5 ? print("变量a大于5") : print("变量a不大于5")
- Swift中三目的特点
- Swift中的三目运算保持了和Objective-C一致的风格;
- Swift中的三目运算符支持空执行的操作,例如上面代码中的
print("变量a不大于5")
永远不会被执行到,这样不会被执行到的代码可以省略为()
。
Switch逻辑分支
- Objective-C中的switch
- 在
Objective-C
中,switch
的分支值类型必须是整数; - 每个语句都需要一句
break
; - 如果要穿透可以省略
break
; - 如果要定义局部变量,必须加
{}
确定该变量的作用域。
- 在
- Swift 中的 switch
-
Swift
中的switch
可以对任意的数据类型进行分支,不再局限于整数; - 一般情况下不需要
break
; - 如果要多值穿透,使用
,
分隔; - 每一个
case
后面必须有可以执行的语句,如果不需要做任何操作才需要使用break
; - 要保证处理所有可能的情况,不然编译器直接报错,不处理的条件可以放在
default
分支中; - 每个分支中定义的临时变量只在当前
case
中有效,不需要再添加{}
。
-
- 代码示例
override func viewDidLoad() { super.viewDidLoad() doSwitch(score : "及格") } func doSwitch (score : String) { switch score { case: “及格”: let name = "员工" print(name + "成绩60~79") case: "良": print("成绩80~89") case: "优": print("成绩90~100") default: break } }
控制台输出结果:
总结
-
Swift
中不存在 C 语言中的非零即真
概念,在逻辑判断的时候必须显式的指明具体的true
或false
; -
??
运算符可以用于判断可选值是否为nil
,如果是nil
就是用后面的值替代; -
if let
和if var
的区别在于{}
里的值是否可以改变; -
guard let
与if let
语法相反,guard let
是Swift2.0
的时候推出的; -
guard let
能够一次性判断每一个值,在真正的代码逻辑部分少了一层嵌套,使代码更加优雅; -
Swift
中的switch
不局限于整数,可以对任意的数据类型进行分支,写法基本与Objective-C
一致。