Swift 2.3 【这些情况下guard要慎用】

12 篇文章 3 订阅

在 Swift 2.0 中,带来了令人激动的的 guard 语句。但是还是有人不太理解 guard 的意义,特别是同 Swift 2.0 之前简单的 if 语句相比较来看。

我们知道,所有的 guard 使用场景都可以用 if 来替代,那么为什么还要增加 guard 特性呢?

其最最主要的原因还是 guard 语法的可读性更强

它可以让我们的方法表意更加明确,更易于阅读,它能够表达“提前退出”的意图,提高了程序的健壮性。

换句话来理解这是 Swift 的设计者在暗示程序员在编写代码时时提早 return 的重要性

但是,并不意味着要将所有的 if ... else ... 和 if let ... 都替换成 guard 语法。

guard 语法很容易被滥用和误用,并不是所有的代码层次结构中都适合 guard 的使用。


那么,什么情况下不适合使用 guard 呢?


Tip 1  不要用 guard —— 作为 if 的相反情况时

作为 if 的相反情况可以理解为作用域内的代码只有在传递进来的条件被判断为 false 的时候才执行

如当我们需要判断一个闭包参数表列中的 error 参数是否有返回值的时候,当 error 为 nil 时我们才有必要执行作用域内的代码,反之 return。

这种情况下用 if 去实现就十分的清晰,可读性更高:

geoCoder.geocodeAddressString(textStr) { (placemarks : [CLPlacemark]?, error : NSError?) in
    // 为了编码的安全性考虑,我们对于必要的参数都要进行判断
    // 如果有 error 那么就退出
    if error != nil { 
        print("error --- \(error)")
        return
    }
    
    // 如果有结果,那么看一下结果是否为空,为空退出
    guard let placemarks = placemarks else {
        return
    }
    
    // 遍历所有的坐标(经纬度)
    for place in placemarks {
        print("wzywzywzy")   
    } 
}


如果用 guard 去处理上面的 error,那么代码就变成了这样:

geoCoder.geocodeAddressString(textStr) { (placemarks : [CLPlacemark]?, error : NSError?) in
    // 如果 error 存在,那么执行作用域内的代码
    guard let error = error else {
        // 如果有结果,那么看一下结果是否为空,为空退出
        guard let placemarks = placemarks else {
            return
        }
        
        // 遍历所有的坐标(经纬度)
        for place in placemarks {
            print("wzywzywzy")
        }
    }
    
    // 作用域代码(存在 error,程序结束)
    print("error --- \(error)")
    return
}


显然,用 guard 去处理上述情况就非常的不妥,造成了 guard 的大括号内还嵌套了一个 for 循环,可读性大大降低。

换句话说,如果你想让这个参数有值并使用它,那么就用 guard,如果你不想让这个参数有值那么就用 if 去判断。这样就可以将错误以及之后的 return 集中在一个大括号内,而顺利执行的作用域代码就在大括号外了。增强了代码的可读性。


Tip 2  不要用 guard —— 不要在 guard 的 else 语句中放入复杂代码

guard 的 else 语句中,不应该放大量的代码,除了简单的提前退出的语句外。如果你在 guard 的 else 代码块中用了其他的代码逻辑或是实现了任何实际功能,那么你就误用了 guard 了。

总之,除一些简单提前退出的语句和一些离开了当前函数的必要操作外,不应该有其他的代码。

最好在 guard 的 else 语句块内不要多过 2 ~ 3 行代码。


Tip 3  不要用 guard —— 不要用 guard 去代替一些比较复杂的 if else 语句

如下面一段代码采用 if else 去实现:

var str : String? = "Hello"

if let helloStr = str where str!.hasPrefix("H") {
    print(helloStr)
} else {
    print("不符合H开头要求")
}

若采用 guard 去实现:

var str : String? = "Hello"

guard let helloStr2 = str where str!.hasPrefix("H") else {
    print("不符合H开头要求")
    return
}
print(helloStr2)

对于这种简单的情况而言,使用 if else 语句比起没有分支的 guard 语法更加容易理解。

最后提醒一点:在使用 guard 的时候,请确保自己已经对可选链有一个正确的了解,guard 可以帮助我们避免使用显示的 if let 进行解包。


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值