Swift的Guard语句

作者: 97c49dfd1f9f | 来源:发表于2015-07-31 01:06 被阅读45382次

本篇文章翻译自:
http://ericcerney.com/swift-guard-statement/
原作者:ecerney
原文章发布于2015-06-10
*译者注:该语法为swift2.0新特性,目前(2015-07-30)仅xcode 7 beta支持,xcode6并不支持。


最开始在Apple的Platform State of the Union看见swift的guard语句的时候,我当时不太理解以后会有什么理由能用到它。这个语句的介绍如下:

与if语句相同的是,guard也是基于一个表达式的布尔值去判断一段代码是否该被执行。与if语句不同的是,guard只有在条件不满足的时候才会执行这段代码。你可以把guard近似的看做是Assert,但是你可以优雅的退出而非崩溃。

即使看了一些例子,我还只是认为这不过是一种更让人困惑的方式,实现我们早已经能够用可选绑定(optional binding)或者单独的if-else语句实现的目的。
直到我开始在Twitter conversation讨论关于这个语句的时候,我才意识到这个语法真的有一些
非常有意思的优点。

Swift Guard保镖Swift Guard保镖

具体细节

让我们用一个简单的对比来比较一下现在的写法和用全新guard语句的写法:

func fooManualCheck(x: Int?) {
    if x == nil || x <= 0 {
        // 不符合值的要求时,写点代码
        return
    }
    
    // 使用x
    x!.description
}

这是最基本的Objective-C方式来保证一个变量真的存在并符合一个条件。没什么大问题,但是有一些缺点:

  1. 你是在检查一个不符合你期望的条件,而非检查你想要的值。如果你加了一堆像这样的条件判断,代码就变的不好理解。你在这里其实是等着你的条件通不过。
  2. 如果前面条件判断的结果不符合了,你还得将你的变量强制拆包。

Swift通过可选绑定让问题变得简单了一些,并解决了上面的部分缺点:

func fooBinding(x: Int?) {
    if let x = x where x > 0 {
        // 使用x
        x.description
    }
    
    // 如果值不符合条件判断,就执行下面的代码
}

这个函数没有了第一个函数的2个缺陷,但引入了一个新的。你把你要写的代码都放在了所有条件判断中,而不是之后。你可能不会马上意识到这个问题,但是你可以想象在你的代码被执行之前,如果嵌套了好多需要被匹配的条件判断,这会变的多难读懂。

对此的解决方法是先对每个条件逐一做检查,如果不符合条件判断就退出。这就会让人容易看出来什么条件会让这个函数退出。

我听说过这个叫保镖模式(Bouncer Pattern),这个模式十分的合理。你要在坏情况进门之前把它们挡出去。这让你每次只考虑一种情况,而不用去搞清楚如何同时将所有的条件判断安排在一起。

这就是guard语句:

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

使用guard语句将上述的3个问题一并解决:

  1. 是对你所期望的条件做检查,而非不符合你期望的。又是和assert很相似。如果条件不符合,guard的else语句就运行,从而退出这个函数。
  2. 如果通过了条件判断,可选类型的变量在guard语句被调用的范围内会被自动的拆包 - 这个例子中该范围是fooGuard函数内部。这是一个很重要,却有点奇怪的特性,但让guard语句十分实用。
  3. 对你所不期望的情况早做检查,使得你写的函数更易读,更易维护。

对非可选类型的变量这种用法也是奏效的:

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

总结

希望上面这个简单的例子告诉你可以马上在你的swift代码中使用guard,从而让你的函数/方法更清楚。对我们来说评判一个新的特性很容易,只要去试一下,看看它对你来说有用没用。

从Objective-C到swift的转变是巨大的,不仅仅是语法,还有你该怎样去看待你的代码架构。只有你主动的去改变自己的意向,每天扩展你自己的模式和方式,你才会从这个绝妙的新语言中收益。

发现了什么其他好玩的东西就告诉我,这个语法对我来说也是新的。

相关文章

  • 为什么Swift中应该避免使用guard语句

    为什么Swift中应该避免使用guard语句 为什么Swift中应该避免使用guard语句

  • guard 和 if 的用法及区别

    一、guard是什么? guard是 swift 2.0推出的新的判断语句的用法。guard语句和if语句类似,都...

  • Swift guard

    guard是什么? guard是 swift 2.0推出的新的判断语句的用法。guard语句和if语句类似,都是根...

  • swift之guard用法

    guard是什么?1.guard是 swift 2.0推出的新的判断语句的用法。guard语句和if语句类似,都是...

  • Swift语句中 if 和 guard 的区别

    对于刚熟悉Swift的Coder来说, 很容易将 if 和 guard 的用法混淆. guard语句最大的优势就是...

  • swift guard语句

    一、表现形式 二、特点 当guard语句的条件为false时,就会执行大括号里面的代码当guard语句的条件为tr...

  • Swift的Guard语句

    本篇文章翻译自:http://ericcerney.com/swift-guard-statement/原作者:e...

  • 学习Swift 2.x中值得注意的新特性

    转眼间,Swift已经一岁半多了,这门新的编程语言确实是值得称赞的。guard语句guard语句,顾名思义,就是守...

  • Swift-控制流(二)

    Swift提供了各种控制流语句。 这些包括while循环来执行多次任务; if,guard和switch语句,以根...

  • Swift 控制流

    Swift提供了多种控制流语句。其中包括while循环,用于多次执行任务;if、guard和switch语句,用于...

网友评论

  • 独白melody:swift关于闭包的操作可谓五花八门。if let guard else ?? as! ……
  • hahand:外国人解释东西,虽然说明方法可能很绕口,但是确实一针见血,直指目标。用guard而不用if原因有两个:1.是用 if 判断,要么在 else 里写处理,要么 判断条件 加非。2.很方便让人看出这段代码用来check的。换句话说,guard应该类似于OC里面的NSAssert, 在复杂逻辑前做好断言,会让调试bug事半功倍。
  • 无夜之星辰:想请教下英文博客你们是怎么找到的
  • 5e144bc5ba83:学习了
  • 山林间迷雾能不能当障眼法的内容:func fooBinding(x: Int?) {
    if let x = x where x > 0 {
    // 使用x
    x.description
    }

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

    这里的x直接用了??? 不用解包了??? 楼主确定????
  • 莫云溪:学习了,的确比if else判断更直观。
  • 曹九朵_:学习了
  • 花郎:hi,提个小意见, if x == nil || x <= 0 应该写成if x == nil || x! <= 0,x值需要拆包才行。另外
    if let x = x where x > 0 {
    return
    }

    where关键字在我的编译器编译错误,提示我用,来分割不同的判断条件,这个有知道什么原因吗
    花郎:@黄联樵 嗯嗯,明白了,感谢
    黄联樵:swift 3 改成用逗号之后,很方便条件的一步一步嵌套,例如:

    if let a = x,
    let b = a,
    let c = b,
    let d = b,
    let e = d {
    **代码块**
    }
    else {
    **代码块**
    }
    黄联樵:现在swift 3是要用逗号,以前是where
  • valentizx:其实说白了 guard就是一个优雅的assert 我是这么理解的。。。因为没接触到更深层次的东西 不敢忘下评论
  • 麟young:函数实现时,guard打头只判断合理条件,保证判断条件简约;而只和else搭配,保证自身低调性,方便guard函数结束后,实现函数主要代码逻辑。总结:guard抽离合理判断条件和不重要逻辑。
  • leftwater:good
  • 巴图鲁:不错
  • af2ec2376e04:swift可有可无的语法糖太多
  • af2ec2376e04:只有带?的值有意义,其他的没意义
    深水日月:应该是需要“如果”这样的判断
  • 7a628d471f4c:请问 此篇及其他文章注明出处可转载吗?
  • 虚心若愚:兄弟看好你。
  • 虚心若愚:写的通俗易懂, 简直 太棒了。
  • 暮归倾城:感谢分享,学习了
  • Azen:吊吊吊!!
  • JinyaMax:学习了 。 简单来说,就是在声明判断条件时 可以直接写上你需要的条件(或者区间),而不必去谨慎地寻找该区间的补集 ,相对来说能减少错误(主要是遗漏),而且代码review时能思路能更清晰。
    piaodang1234:@happycoder 你把你要写的代码都放在了所有条件判断中,而不是之后。你可能不会马上意识到这个问题,但是你可以想象在你的代码被执行之前,如果嵌套了好多需要被匹配的条件判断,这会变的多难读懂。 这是不使用if的原因
    bf7edeaa0ddd:@JinyaTu if 不也可以直接写上需要的条件(或者区间吗)
    我的大好时光:@金亞 分析的好透彻
  • 七夕猪:例子中的 func fooNonOptionalBad: 是不是少写了 guard 关键字啊?
    七夕猪:@七夕猪 明白了,不是少写了,这个函数是辅助理解 func fooNonOptionalGood: 这个函数的吧。
  • David_Do:学习了。。。
  • 悲伤的盖茨比:感谢,学习了
  • GloryMan:学习了
  • 037e031e1cef:感谢分享
  • iTychoo:感谢, 学习了!
  • 贾亦真亦贾:学习了

本文标题:Swift的Guard语句

本文链接:https://www.haomeiwen.com/subject/dytvqttx.html