Swift基础之守卫语句guard
本篇文章翻译自:
http://ericcerney.com/swift-guard-statement/
原作者:ecerney
该语法为swift2.0之后添加的新特性
最开始在Apple的Platform State of the Union看见swift的guard语句的时候,我当时不太理解以后会有什么理由能用到它。这个语句的介绍如下:
与if语句相同的是,guard也是基于一个表达式的布尔值去判断一段代码是否该被执行。与if语句不同的是,guard只有在条件不满足的时候才会执行这段代码。你可以把guard近似的看做是Assert,但是你可以优雅的退出而非崩溃。
即使看了一些例子,我还只是认为这不过是一种更让人困惑的方式,实现我们早已经能够用可选绑定(optional binding)或者单独的if-else语句实现的目的。
直到我开始在Twitter conversation讨论关于这个语句的时候,我才意识到这个语法真的有一些非常有意思的优点。
具体细节
让我们用一个简单的对比来比较一下现在的写法和用全新guard语句的写法:
func fooManualCheck(x: Int?) {
if x == nil || x <= 0 {
// 不符合值的要求时,写点代码
return
}
// 使用x
x!.description
}
这是最基本的Objective-C方式来保证一个变量真的存在并符合一个条件。没什么大问题,但是有一些缺点:
- 你是在检查一个不符合你期望的条件,而非检查你想要的值。如果你加了一堆像这样的条件判断,代码就变的不好理解。你在这里其实是等着你的条件通不过。
- 如果前面条件判断的结果不符合了,你还得将你的变量强制拆包。
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个问题一并解决:
- 是对你所期望的条件做检查,而非不符合你期望的。又是和assert很相似。如果条件不符合,guard的else语句就运行,从而退出这个函数。
- 如果通过了条件判断,可选类型的变量在guard语句被调用的范围内会被自动的拆包 - 这个例子中该范围是fooGuard函数内部。这是一个很重要,却有点奇怪的特性,但让guard语句十分实用。
- 对你所不期望的情况早做检查,使得你写的函数更易读,更易维护。
对非可选类型的变量这种用法也是奏效的:
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基础之Demo包含刷新,加载,网络请求,MVC
Swift中有一个Alamofire第三方是进行网络请求的,它是AFNetworking的作者写的Swift形式,今天先介绍一下,利用pod导入AFNetworking,SVProgressHUD,M ...
- swift基础:第二部分:函数和闭包
今天本来想利用上午的时间本来打算将swift基础部分学习完的,不巧的是,后台来和我讨论用户评价的接口,讨论过后,商讨出一种可行的方案,十几分钟时间过去了,我拿到将接口介入到已经完成的页面中,完美,终于 ...
- Swift基础语法学习总结(转)
Swift基础语法学习总结 1.基础 1.1) swift还是使用// 和/* */ 来注释,并且/* */允许多行注释. 1.2) swift使用print和println打印,它的传参是一个泛型 ...
- Swift基础语法学习总结
Swift基础语法学习总结Swift高级语法学习总结Swift语法总结补充(一) 1.基础 1.1) swift还是使用// 和/* */ 来注释,并且/* */允许多行注释. 1.2) swift ...
- Swift基础学习
Swift基础学习 http://c.biancheng.net/cpp/html/2242.html 这个网站最近看了一下,对于基本语法解释概括的相对全面,如同重新练习一遍OC似的,挺全面的,谢谢 ...
- swift基础:第六部分:类与对象
http://reactnative.cn/docs/0.24/getting-started.html#content(react Native 开发文档) 互联网这个时代,你松懈一天,就会有很多很 ...
- 15个初学者必看的基础SQL查询语句
本文由码农网 – 小峰原创翻译,转载请看清文末的转载要求,欢迎参与我们的付费投稿计划! 本文将分享15个初学者必看的基础SQL查询语句,都很基础,但是你不一定都会,所以好好看看吧. 1.创建表和数据插 ...
- Swift基础语法 、 元组(Tuple)
字符串的使用 1.1 问题 Swift的String和Character类型提供了一个快速的,兼容Unicode的方式来处理代码中的文本信息.创建和操作字符串的语法与C语言中字符串类似.本案例将学习如 ...
- VBS基础篇 - 循环语句(3) - For...Next
VBS基础篇 - 循环语句(3) - For...Next 指定循环次数,使用计数器重复运行语句,语法结构如下: 1 2 3 4 5 For counter = start To end [Ste ...
随机推荐
- 使用python实现人脸检测
人脸检测 人脸检测使用到的技术是OpenCV,上一节已经介绍了OpenCV的环境安装,点击查看. 功能展示 识别一种图上的所有人的脸,并且标出人脸的位置,画出人眼以及嘴的位置,展示效果图如下: 多张脸 ...
- HTTP与HTTPS
一.HTTP和HTTPS的基本概念 HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),用于从WWW服务器传输超文本到本地浏览器的传输协议,它可以使浏览器 ...
- [ZJOI2016]小星星
题目描述 小Y是一个心灵手巧的女孩子,她喜欢手工制作一些小饰品.她有n颗小星星,用m条彩色的细线串了起来,每条细线连着两颗小星星. 有一天她发现,她的饰品被破坏了,很多细线都被拆掉了.这个饰品只剩下了 ...
- hdu 4283 区间dp
You Are the One Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- ●BZOJ 1042 [HAOI2008]硬币购物
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1042 题解: 容斥原理,dp预处理首先跑个无限物品的背包dp求出dp[i]表示在四种物品都有 ...
- [BZOJ]3671 随机数生成器(Noi2014)
洛谷上卡不过去的朋友们可以来看看小C的程序(小C才不是标题党呢!) Description Input 第1行包含5个整数,依次为 x_0,a,b,c,d ,描述小H采用的随机数生成算法所需的随机种子 ...
- 关于HttpClient重试策略的研究
一.背景 由于工作上的业务本人经常与第三方系统交互,所以经常会使用HttpClient与第三方进行通信.对于交易类的接口,订单状态是至关重要的. 这就牵扯到一系列问题: HttpClient是否有默认 ...
- ORACLE 启动过程
1 STARTUP NOMOUNT 1.读取环境变量下dbs目录下的参数文件(spfile/pfile) 查找参数文件的顺序如上面列表的,读取优先级: spfilechongshi.ora > ...
- SpringBoot跨域问题解决方案
一.允许全部请求跨域许可的代码: 需要继承WebMvcConfigurerAdapter类 @Configuration public class MyWebAppConfigurer extends ...
- python 中常见绘图属性
fig = plt.figure(facecolor='w')#生成图 ax = fig.add_subplot(111, projection='3d')#绘制子图 ax.scatter(t[0], ...