【问题标题】:Return statement in IF LET vs GUARD LETIF LET 与 GUARD LET 中的返回语句
【发布时间】:2017-08-29 11:02:02
【问题描述】:

看下面两个代码相同的场景:

使用 IF LET:

public func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?){
    if let error = error {
        print("error: \(error.localizedDescription)")
        return
    }
        for service in peripheral.services!
        {
            print("discovered service is ::::",service)
        }
}

使用 GUARD LET:

public func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?){
        guard let _ = error else{
            for service in peripheral.services!
            {
                print("discovered service is ::::",service)
            }
        return
       }
    }

他们都在使用return statement,而且他们的目的都是一样的,那么有什么区别,哪个更好?

编辑:-

问题在于一般性陈述,使用其中任何一个都可以,但是当我们遇到错误来处理哪个最好使用时?

【问题讨论】:

  • 这是一个奇怪的函数,会传入这样的错误。因此,它不太适合这种比较。
  • @Shubham Mishra 再多一点 + 带守卫 let is ,它还提供了 break 的使用,主要目的是保持代码的干净和可读性。
  • 问题是一般性陈述,这很好,但是当我们有错误来处理最好使用的?
  • @ShubhamMishra 它是您想要的选择。在引入 guard let 之前,我们使用了 if let。但这让代码看起来很复杂,有很多嵌套和额外使用 {}。这被guard let克服了。用例与处理零值崩溃的用例相同,但也有助于保持代码干净和易于理解。

标签: ios swift3


【解决方案1】:

首先,它们都没有正确实施。

  • peripheral.services! 中,如果services 为nil,它将崩溃。
  • return 声明 - 两者都没有必要 return,您可以将其从 if-let 中删除,一切都会正常
  • guard 优于 if-let 的好处是它减少了 if-else 括号,从而产生更多可读代码
  • 如果您关心块范围外的变量值,请使用guard,请考虑if-let,您只能在块内使用未包装的变量。
  • 使用if-let 解包少量变量,并且在块范围外不需要解包变量的值
  • 使用guard-else 在块范围外使用解包变量
  • 如果您要在块范围之外使用error 对象(主要使用保护块),则使用guard-else,否则使用if-let

【讨论】:

  • 如果error不是nil那么只有service会是nil,并且已经完成了错误检查
  • 并非总是如此,因为services 是可选的,您应该使用if-letguard-else 解开它
  • 知道了,但问题是一般性的陈述,这很好,但是当我们遇到错误时,最好使用哪一个?
【解决方案2】:

在这种情况下使用guard 使您的意图更加清晰——您只希望函数在没有错误的情况下执行。

我最喜欢guard 的地方在于它可以防止您深入嵌套if 括号,从而使代码更具可读性。但是,在您的代码中,为了实现这一点,您可以将其置于如下格式:

guard error != nil else { return }
... // continue with regular code

除了 guardif 产生相同的结果之外,这主要是口味问题。

【讨论】:

  • 问题是一般性陈述,这很好,但是当我们有错误来处理最好使用的?
【解决方案3】:

Guard 语句非常适合处理“末日金字塔”。我使用它的方式是例如键盘通知:

func keyboardWillShowSelector(notification:NSNotification) {
        guard let userInfo = notification.userInfo else { return }
        var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
        keyboardFrame = self.view.convert(keyboardFrame, from: nil)
        let height = keyboardFrame.size.height
        keyboardWillShow(withHeight: height)
}

如果没有guard语句,它会有另一个意图,代码不会那么干净:

func keyboardWillShowSelector(notification:NSNotification) {
        if let userInfo = notification.userInfo {
            var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
            keyboardFrame = self.view.convert(keyboardFrame, from: nil)
            let height = keyboardFrame.size.height
            keyboardWillShow(withHeight: height)
        }
}

另一个很好的例子是验证:

private func errorFromInputValidation(name: String, email: String, password1: String, password2: String) -> String? {
        guard password1 != "" && password2 != "" && email != "" && name != ""  else { return Localizable.fieldsCannotBeEmpty.localized }
        guard password1 == password2 else { return Localizable.passwordsAreNotEqual.localized }
        return nil
}

【讨论】:

  • 问题是一般性陈述,这很好,但是当我们有错误来处理最好使用的?
  • 视情况而定,你可以用 if 和 guard 来实现一切。只是为了让代码更干净。
猜你喜欢
  • 1970-01-01
  • 2021-05-02
  • 1970-01-01
  • 2017-05-29
  • 2018-09-16
  • 2021-03-27
  • 2016-08-15
  • 1970-01-01
  • 2014-03-29
相关资源
最近更新 更多