与 if 语句相同的是,guard 也是基于一个表达式的 bool 值去判断一段代码是否该被执行。
与 if 语句不通的是,guard只有在条件不满足的时候才会执行这段代码。可以把 guard 近似看做是 Assert。
具体细节
简单的例子:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 
 | func fooManualCheck(x: Int?) {if x == nil || x <= 0 {
 
 return
 }
 
 
 
 x!.description
 }
 
 | 
以上是最基本的 OC 方式来保证一个变量的值是否符合我们的要求。
有两个缺点:
- 你是在检查一个不符合你期望的条件,而并非你想要的值。
- 如果前面条件判断的结果不符合后,要想使用 x 你还得将变量强制拆包解绑。
使用 swift 可选绑定,如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 
 | func fooBinding(x: Int?) {if let x = x where x > 0 {
 
 x.description
 }
 
 
 }
 ```
 
 这样写代码会有一个缺陷,你可能目前并未察觉,但是如果真应用到项目中时,你会发现,你的代码被执行前,如果嵌套了很多需要被匹配的条件判断,会变得非常难以理解。
 
 对此解决方法:对每个条件逐一检查,如果不符合条件判断就退出。会让人比较容易开出什么条件会让这个函数退出,这就是**保镖模式**。
 
 于是就有了 guard 语句:
 
 ```swift
 func fooGuard(x: Int?) {
 guard let x = x where x > 0 else {
 
 return
 }
 
 
 x.description
 }
 
 | 
这样写的好处:
- 相当于 if 的反向语句,{}内需要写的代码是条件不符合的代码。
- 如果通过了条件判断,可选类型的变量在 guard 语句被调用的范围内会被自动拆包 - 这个例子中,该范围是 fooGuard 函数内部。
- 对不希望的情况早做检查,让你写的函数更易读。
对非可选变量也是很好的:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 
 | func fooNonOptionalGood(x: Int) {guard x > 0 else {
 
 return
 }
 
 
 }
 
 func fooNonOptionalBad(x: Int) {
 if x <= 0 {
 
 return
 }
 
 
 }
 
 |