Defer inside a loop captures the loop variable by reference, causing all deferred calls to use the final value; fix by creating a local copy of the variable inside the loop.
The defer statement inside a loop captures the loop variable by reference, causing all deferred functions to execute with the variable's final value after the loop ends. To fix this, create a new local variable inside the loop body and defer using that variable instead.
for i := 0; i < n; i++ {
idx := i // Capture current value
defer func() {
fmt.Println(idx)
}()
}
In Go 1.22 and later, loop variables are automatically scoped per iteration, so this pattern is no longer required.
When you put a defer inside a loop, Go waits until the function finishes to run those deferred actions. By that time, the loop variable has already reached its final value, so every deferred action sees the same number instead of the one from its specific loop iteration. You fix this by copying the loop variable into a new local variable inside the loop so the deferred function captures the correct value for that specific run.