guard

与 if 语句相同的是,guard 也是基于一个表达式的 bool 值去判断一段代码是否该被执行。

与 if 语句不通的是,guard只有在条件不满足的时候才会执行这段代码。可以把 guard 近似看做是 Assert。

具体细节

简单的例子:

1
2
3
4
5
6
7
8
9
10
func fooManualCheck(x: Int?) {
if x == nil || x <= 0 {
// 不符合值得要求时,需要执行的语句
return
}

// 来到这说明 x 肯定符合要求

x!.description
}

以上是最基本的 OC 方式来保证一个变量的值是否符合我们的要求。
有两个缺点:

  1. 你是在检查一个不符合你期望的条件,而并非你想要的值。
  2. 如果前面条件判断的结果不符合后,要想使用 x 你还得将变量强制拆包解绑。

使用 swift 可选绑定,如下:

1
2
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
x.description
}

// 如果值不符合条件判断,就执行下面的代码
}
```

这样写代码会有一个缺陷,你可能目前并未察觉,但是如果真应用到项目中时,你会发现,你的代码被执行前,如果嵌套了很多需要被匹配的条件判断,会变得非常难以理解。

对此解决方法:对每个条件逐一检查,如果不符合条件判断就退出。会让人比较容易开出什么条件会让这个函数退出,这就是**保镖模式**。

于是就有了 guard 语句:

```swift
func fooGuard(x: Int?) {
guard let x = x where x > 0 else {
// 变量不符合条件判断时,执行下面代码
return
}

// 使用x
x.description
}

这样写的好处:

  1. 相当于 if 的反向语句,{}内需要写的代码是条件不符合的代码。
  2. 如果通过了条件判断,可选类型的变量在 guard 语句被调用的范围内会被自动拆包 - 这个例子中,该范围是 fooGuard 函数内部。
  3. 对不希望的情况早做检查,让你写的函数更易读。

对非可选变量也是很好的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
func fooNonOptionalGood(x: Int) {
guard x > 0 else {
// 变量不符合条件判断时,执行下面代码
return
}

// 使用x
}

func fooNonOptionalBad(x: Int) {
if x <= 0 {
// 变量不符合条件判断时,执行下面代码
return
}

// 使用x
}
文章作者: Ammar
文章链接: http://lizhaoloveit.cn/2016/04/21/guard/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ammar's Blog
打赏
  • 微信
  • 支付宝

评论