根据Apple Swift文档推迟
此语句允许您执行任何必须执行的清理,无论执行如何离开当前代码块,无论它是因为抛出错误还是由于返回或中断等语句而离开。
但是这段代码:
enum SomeError: ErrorType {
case BadLuck
}
func unluckey() throws {
print("\n\tunluckey() -> someone will have a bad day ;)\n")
throw SomeError.BadLuck
}
func callsUnluckey() throws {
print("callsUnluckey() -> OPENING something")
defer {
print("callsUnluckey() -> CLOSEING something")
}
print("callsUnluckey() -> WORKING with something")
try unluckey()
print("callsUnluckey() -> will never get here so chill...")
defer {
print("callsUnluckey() -> why this is not getting called?")
}
}
do {
try callsUnluckey()
} catch {
print("")
print("someone had a bad day")
}
在控制台中生成此结果:
callsUnluckey() -> OPENING something
callsUnluckey() -> WORKING with something
unluckey() -> someone will have a bad day ;)
callsUnluckey() -> CLOSEING something
someone had a bad day
我的问题是:为什么callUnluckey()的最后一次推迟没有被调用?。
答案 0 :(得分:4)
查看The Swift Programming Language中汇总的语言语法:defer
是一个语句。在语法中,语句是必须按顺序运行的命令(与程序元素的定义相反,如类或函数,稍后将在命令式代码中使用)。
请注意在您引用的部分之后的位,依赖于顺序。如果defer
只是一个声明,如函数或属性或类型声明,则不会有排序效果。 (例如,将函数声明放在什么顺序并不重要。)
defer
之后放置return
,编译器会抓住你,注意它是永远不会被执行的代码。
请记住,Swift中的“投掷”实际上只是一种特殊的返回类型。因此,如果您的函数throw
s,throw
之后的代码将不会被执行(因此没有defer
语句将能够设置代码块以便稍后执行)。当你声明一个函数throws
时,对其他抛出函数的任何调用都会有效地成为一个可能的throw
语句,它本身就是一个返回。