Did you know this about defer in Swift?

A couple of weeks ago I started taking a look into Golang, since at Axiom Zen we’ve been using it quite a lot, and I realized it also uses defer statements which basically are the same as in Swift.

Interestingly, when I was learning about stacking defers, I had to stop to ask myself.

What does this output in Swift?

func some() {
for i in 0..<10 {
defer { print(i) }
}
}

Since Golang uses a stack for its defers, this in Go prints 9, 8, 7, …, 0.

Golang and Swift

What about Swift?

Well, Swift prints 0, 1, 2, …, 9.

So Swift uses a queue, right?

Wrong!

defer in Swift also uses a stack, but how the defer statement works refers to the current scope, that is, it only defers inside the for scope in the example.

Every time through the for loop, the defer stack is popped, and that’s why it prints the numbers in ascending order.

In the case of:

func someOther() {
defer { print("a") }
defer { print("b") }
}

This will just stack the defers and simply print b, a as I was expecting.

And:

func extra() {
for i in 0..<10 {
defer { print("a") }
defer { print("b") }
}
}

Will just print b, a, b, a, b, a, …, b, a.

Interesting isn’t it?

Well, I thought it was! 😁