Home
The defer keyword in Go
The defer
keyword delays the execution of a code expression until the surrounding function returns. It is useful to run code that needs to be executed whatever the flow of a function, even after a panic.
func main() {
defer fmt.Println("world")
fmt.Println("hello")
}
// Output:
// hello
// world
func main() {
defer fmt.Println("world")
fmt.Println("hello")
panic("boom")
}
// Output:
// hello
// world
// panic: boom
Deferred function calls are pushed onto a stack, and then they are executed in last-in-first-out order. This can cause undesired behavior when used inside a loop:
func main() {
for i := 0; i < 3; i++ {
defer fmt.Println("world")
fmt.Println("hello")
}
}
// Output:
// hello
// hello
// hello
// world
// world
// world
A solution is to wrap the logic in a function:
func main() {
for i := 0; i < 3; i++ {
func() {
defer fmt.Println("world")
fmt.Println("hello")
}()
}
}
// Output:
// hello
// world
// hello
// world
// hello
// world
One thing to keep in mind is that directly deferring a function call ignores its return value, so in cases where it is needed, a deferred anonymous function can be used to access those values:
func main() {
defer func() {
err := mightError()
if err != nil {
fmt.Println(err)
}
}()
fmt.Println("foo")
}
func mightError() error {
return errors.New("boom")
}
// Output:
// foo
// boom