Swift|Swift 2.0之错误处理(下)
在上一篇文章中,我们学习了 Swift 2.0 错误处理的基本用法。
这篇文章将继续介绍 Swift 2.0 配合错误处理的两个新关键字,defer
与 guard
。
defer
defer
关键字可以用来包裹一段代码,这个代码块将会在当前作用域结束的时候被调用。这通常被用来对当前的代码进行一些清理工作,比如关闭打开的文件等。
可以在同一个作用域中指定多个 defer
代码块,在当前作用域结束时,它们会以相反的顺序被调用,即先定义的后执行,后定义的先执行。
例如下面的代码:
openFile()
defer {
// defer block 1
closeFile()
}startPortListener(42)
defer {
// defer block 2
stopPortListener(42)
}
这段代码在作用域结束的时候,第二个
defer
块将首先被调用,其次再调用第一个 defer
块。guard 【Swift|Swift 2.0之错误处理(下)】
guard
关键字与 if
很相似, 只是作用与它相反。我们通常使用 if
用来选择自己想要的条件,而 guard
则是用来选择不想要的条件。比如,有个程序员俱乐部规定在 github 上的 star 数少于 200 的不得入内。如果用
if
来进行判断,代码是这样的:if star < 200 {
return
}
如果使用
guard
的话,则应该是:guard star >= 200 else {
return
}
对于可选类型的绑定来说,
guard
关键字的好处更加明显。下面的代码对比了这两种方法:var star: Int?if let star = star {
// star 现在已经可以放心地使用了
}guard let star = star else {
return
}
// 从这里到本作用域结束,star都可以放心使用了
从段代码中可以看到,如果使用普通的
if-let
来对可选类型进行绑定,则意味着,我们必须在 if
语句的大括号里处理正常的情况,而在外面处理错误的情况。这与我们的直观感觉(特别是强迫症患者)不符。但是如果使用 guard
的话,我们可以提前判断出空的可选值,然后提前退出,在错误判断之后的代码中,star
都是解包过的,可以放心使用了。Show me the code 这里继续使用上一篇文章中的 Demo,上一章的完整代码可以从我的github上下载到,文件名为
01-ErrorHandling.playground
。在
starterShelf
函数之前,添加两个函数的定义:func beginReceipt() {
print("又要开始大采买了,真是买书如山倒啊")
}func endReceipt() {
print("购物结束,该去剁手去了")
}
接着,在调用
purchaseBooks
方法的前后,调用刚刚定义的两个函数:do {
beginReceipt()try shelf.purchaseBooks(2500)endReceipt()
} catch BookShelfError.NoEnoughSpace(let required) {
print("书柜满啦,新买的书放不下咯。还差\(required)个空位,赶紧买个新书柜吧")
}
可以看到, 只有前一个函数的信息被打印出来了,那是因为在执行
purchaseBooks
方法的时候抛出了错误,程序的控制流程被转到了 catch
代码块里面,第二个函数没有获得执行。这里,就可以使用
defer
来让 endReceipt
在 do
的作用域结束之前得到调用:do {
beginReceipt()
defer {
endReceipt()
}try shelf.purchaseBooks(2500)
} catch BookShelfError.NoEnoughSpace(let required) {
print("书柜满啦,新买的书放不下咯。还差\(required)个空位,赶紧买个新书柜吧")
}
现在,假设我们使用了一个字典来保存要在哪个书店购买几本书,将下面代码添加在
BookShelfError
的定义下面:let shopList = ["新华书店": 250]
在调用
purchaseBooks
的时候,先从 shopList
里面取出要购买的数量:
do {
// ...let buyCount = shopList["新华书店"]
try shelf.purchaseBooks(buyCount)
}
如果直接这样调用的话,编译器会报错,因为字典类型返回的是一个
Int?
的可选类型,所以不能直接使用。这里,
guard
关键字就可以派上用场了:do {
// ...guard let buyCount = shopList["新华书店"] else {
fatalError()
}try shelf.purchaseBooks(buyCount)
}
这时,程序就就可以正常运行了。
作为练手,可以将
purchaseBooks
和 lendBooks
两个方法定义中的 if
改成使用 guard
,这个很简单,就留给大家自己去尝试了。本篇的完整代码可以到我的github上进行下载。
推荐阅读
- Win8大提速技巧之禁用Multimedia
- 投稿|数字藏品的冰与火之歌
- 是他发起了《权力的游戏》,他是将所有人拖入命运漩涡的混乱之神(下)
- 系统之家Win7解密几种经常见的黑客入侵手段与应对技巧
- 释放系统之家win7旗舰版iso系统HD音量的设置步骤
- 安装系统 重装系统之家win7纯净版gho系统后检测不到U盘怎样处理
- 查看系统之家纯净win7系统进程PID标识符的技巧
- 系统之家精简纯净win7系统出现winlogon.exe应用程序出错的处理办法
- win7系统之家教你怎样在Windows7下安装Windows10成为双系统
- 中关村系统之家教你将XP升级win7前需排查的兼容性问题