What does this print? (Defer order during panic)
Question 308HardGo 1.22 to 1.25
func main() {
defer fmt.Println("1")
defer func() {
r := recover()
fmt.Println("recovered", r)
}()
defer fmt.Println("3")
fmt.Println(f())
panic("boom")
}
func f() (n int) {
defer func() { n *= 2 }()
return 21
}
Output:
42
3
recovered boom
1
f: return 21 assigns n = 21, then deferred functions run and can change named results, so the caller gets 42. In main, a panic runs the deferred calls in LIFO order. "3" prints first. The next defer recovers "boom", which stops the panic, so the remaining defer ("1") still runs and main returns normally with exit code 0. Also note that arguments to a deferred call are evaluated when defer executes, not when the call runs. defer fmt.Println(x) captures the value of x at that moment.
More on Error Handling & panics
- Q306What does this print? (Rules of
recover) - Q307A goroutine panics. Can a
recoverinmaincatch it? How do you protect background goroutines? - Q309How do you convert a panic into an error returned from a function?
- Q310What happens with
panic(nil)and with re-panicking? How did Go 1.21 change this? - Q311Which runtime failures can't be recovered with
recover? - Q312Compare
panic,os.Exit,log.Fatalandruntime.Goexitwith respect to deferred functions.