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