Swift的Guard语句

转自:http://www.jianshu.com/p/3a8e45af7fdd

本篇文章翻译自:
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保镖

具体细节

让我们用一个简单的对比来比较一下现在的写法和用全新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的转变是巨大的,不仅仅是语法,还有你该怎样去看待你的代码架构。只有你主动的去改变自己的意向,每天扩展你自己的模式和方式,你才会从这个绝妙的新语言中收益。

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

文/ray16897188(简书作者)
原文链接:http://www.jianshu.com/p/3a8e45af7fdd
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

时间: 2024-11-20 09:32:16

Swift的Guard语句的相关文章

Swift 控制传递语句

控制传递语句(Control Transfer Statements) 控制转移语句改变你代码的执行顺序,通过它你可以实现代码的跳转.Swift有四种控制转移语句. continue break fallthrough return 我们将会在下面讨论continue.break和fallthrough语句.return语句将会在函数章节讨论. Continue continue语句告诉一个循环体立刻停止本次循环迭代,重新开始下次循环迭代.就好像在说"本次循环迭代我已经执行完了",但是

OC与Swift在判读语句中的区别

11.swift中的switch结构 区别一: oc中switch条件只可以放整数 swift中switch条件可以放几乎任何数据类型 区别二: oc中每一个case中应有break,如果没有break,则会继续向下贯穿执行case直到碰见break跳出switch结构 swift中不需要在case分支最后添加break语句,该case分支执行完成后,会跳出switch结构 区别三: oc中不是每个case后面必须有可执行语句,如果某个case分支中没有可执行语句和break,则该分支将会执行其

swift笔记-if语句

//1.基本使用 let num = 23 if num > 10 { print("num is big") }else if num < 0 { print("num is fushu") }else{ print("num is mid") } swift中,if后面跟的条件语句必须是boolType表达是,像在OC中的if(num)在swift中便不能使用了 2.if let的理解 var optionalName: Stri

Swift 另类判断语句用法 button.selected = index &lt; rating

很简洁的用法: index < rating return true or false for (index, button) in ratingButtons.enumerate() { // If the index of a button is less than the rating, that button should be selected. button.selected = index < rating } 大大简化了语句,可读性很强.对比老写法: button.select

Swift for循环语句,注意跟以前的不一样

/** 1. 老得for语句不能再使用了.如:for(int i=0; i<4; i++) 2. 新的方式:for i in 0..<5 表示[0, 5):for i in 0...5 表示 [0, 5] 3. 新的方式的倒序 for i in (0..<5).reversed() 表示 (5, 0]:for i in (0...5).reversed() 表示[5, 0] */ class ViewController: UIViewController { override func

Swift - 24 - switch语句的高级用法

//: Playground - noun: a place where people can play import UIKit // 对区间进行判断 var score = 90 switch score { case 0: print("You got an egg!") case 1..<60: print("Sorry, you failed.") case 60..<70: print("Just passed.") ca

Swift Guard Statement

When the first saw the Swift guard statement during Apple’s Platform State of the Union, I couldn’t quite understand why I would ever use it. So what is it? Like an if statement, guard executes statements based on a Boolean value of an expression. Un

比 UICollectionView更好用的IGListKit教程

原文:IGListKit Tutorial: Better UICollectionViews 作者:Ryan Nystrom 译者:kmyhy 每个 app 都以同样的方式开始:几个界面,几颗按钮,一两个 list.但随着进度的进行以及 app 膨胀,功能开始发生变化.你简单的数据源开始在工期和产品经理的压力下变得支离破碎.再过一久,你留下一堆庞大得难以维护的 view controller.今天,IGListKit 来拯救你了! IGListKit 专门用于解决在使用 UICollectio

swift 简单语句 控制流语句

在 Swift 中.有两种类型的语句:简单语句和控制流语句.简单语句是最常见的.用于构造表达式和声明.控制流语句则用于控制程序运行的流程,Swift 中有三种类型的控制流语句:循环语句.分支语句和控制传递语句. 循环语句用于反复运行代码块.分支语句用于运行满足特定条件的代码块:控制传递语句则用于改动代码的运行顺序.在稍后的叙述中,将会具体地介绍每一种类型的控制流语句. 是否将分号(;)加入到语句的结尾处是可选的.但若要在同一行内写多条独立语句,请务必使用分号. GRAMMAR OF A STAT