I have the following swift code executing in playground:
func A() {
print ("Hello")
guard 1 == 2 else {
return
}
defer {
print ("World")
}
}
A()
I expected to see
Hello
World
Instead only the Hello
is printed. Why is this? What am I missing?
Here is a better example:
enum MyError: ErrorType {
case TriggerDefer
}
func throwsMyError() throws {
let myzero = Int(arc4random_uniform(1))
guard myzero > 1 else {
throw MyError.TriggerDefer
}
}
func A() throws {
try throwsMyError()
defer {
print ("Hello World")
}
}
enum MyError: ErrorType {
case TriggerDefer
}
func throwsMyError() throws {
let myzero = Int(arc4random_uniform(1))
print("Hello")
guard myzero > 1 else {
throw MyError.TriggerDefer
}
}
func A() throws {
defer {
print ("World")
}
try throwsMyError()
}
The output will now be
Hello
World
What you're missing is that defer
is not magic. It is executable code, just like any other code. If the path of execution never encounters it, there is nothing to be deferred. This is why it should always be dead first in the block on whose exit it is to be executed — so that we guarantee that it is encountered.