Swift guard 语句的一些个人理解

1,081 阅读2分钟

「这是我参与2022首次更文挑战的第2天,活动详情查看:2022首次更文挑战」。

在 Swift 中,guard 语句可以让我们很方便的控制代码流程走向。

比如:在我们执行 postMail() 函数时,应该首先判断接收人邮箱不为空,且邮件内容不为空。这种逻辑就可以使用 guard 语句来实现。

什么是 guard

guard 的中文意思为守卫。顾名思义,它的作用就是用来守卫我们的代码安全的。下面是它的语法:

guard <condition> else { return }

guard 的判断条件应该是 Bool 值或者对 Optional 值得一个解包操作:

func postMail(receiver: String?, content: String?, immediately: Bool) {
    // Optioanl
    guard let receiver = receiver, let content = content else {
        return
    }
    
    // Bool
    guard immediately else {
        // do some thing
        return
    }
    // do some thing
}

通过上述代码,可以看出:业务代码会在 receiver 和 content 真正有值的时候才会被执行,否则直接 return。这大大的减少代码中关于值缺失而造成的 bug。

除了 return,你也可以使用以下关键字来跳出当前代码流程:

  • break:跳出枚举的 switch-case。
  • continue:跳出当前 for-loop。
  • throw:直接抛出异常。

大家可能此时会有一个疑问?这些我也可以用 if 来实现啊,那我怎么知道什么时候用 guard?什么时候用 if 呢?

下面,就来聊一下各自的使用场景。

适用 guard 的使用场景

对于我的个人经验来说,当一些先决条件不满足,后续代码没必要执行的情况下,就应该去使用 guard。

比如,在 APP 中最常见的登录页面。先决条件就是用户必须填写用户名和密码。如果这两项任意一项为空,那后面的登录逻辑是没必要再去执行的。

func log(account: String, pwd: String) {
    guard !account.isEmpty && !pwd.isEmpty else {
        return
    }
    // 登录逻辑
}

这里需要特别注意的是:guard 只有条件为真时,才会执行后面的代码。所以上面的条件千万不要写成下面这种:

guard account.isEmpty && pwd.isEmpty else {
    return
}

这种情况,使用 if 当然也是可以的,逻辑上也没有什么问题。但使用 guard 会使你的代码更加易读,一看就知道必须满足那几个条件,这无形中会减少代码出问题的几率。

适用 if 的使用场景

当一些业务代码,在不满足某些条件的情况下,也需要执行的时候,就轮到 if 出场了。

func executeTask(finished: Bool) {
    if finished {
        doFinisher()
    }
    
    doCommonTask()
}

上述代码就不适宜用 guard,因为用了 guard 之后, doCommonTask() 就没有机会执行了。

总结

  • guard 的判断条件为 Bool 或者用于 Optional 解包。
  • guard 的好处:代码清晰易读,减少 bug 出现的几率。
  • 当条件不满足,后续代码无需执行时,使用 guard。
  • 不管条件满不满足,后续代码都需执行时,使用 if。