How Defer Works with Functions in Go

Order and Gotchas

Go executes deferred functions in reverse order of their appearance, evaluating arguments immediately at the time of deferral.

In Go, defer statements are executed in Last-In-First-Out (LIFO) order when the surrounding function returns. Arguments to deferred functions are evaluated immediately when the defer statement is encountered, not when the function actually runs.

func main() {
    x := 1
    defer func() { fmt.Println(x) }() // Prints 1 (evaluated now)
    x = 2
    defer func() { fmt.Println(x) }() // Prints 2 (evaluated now)
    // Execution order: second defer, then first defer
}

This means if you modify a variable after deferring a function that uses it, the deferred function will see the old value unless you capture the variable explicitly or defer a function that reads the variable at execution time.