Go

What does this print before Go 1.22 and in Go 1.22+?

Question 478MediumGo 1.22 to 1.25
func main() {
    var wg sync.WaitGroup
    var ptrs []*int
    for i := 0; i < 3; i++ {
        ptrs = append(ptrs, &i)
        wg.Add(1)
        go func() {
            defer wg.Done()
            fmt.Print(i, " ")
        }()
    }
    wg.Wait()
    for _, p := range ptrs {
        fmt.Print(*p, " ")
    }
}

Before 1.22: the loop had one variable i shared by all iterations. The goroutines usually print 3 3 3 (it is a data race, so any of 0..3 is possible), and the pointers all point to the same variable, printing 3 3 3.

Go 1.22+: each iteration gets a fresh i. Goroutines print 0 1 2 in some order (scheduling is nondeterministic) and the pointers print 0 1 2.

Gotcha: the semantics are chosen by the go directive in go.mod, not the toolchain version. A module declaring go 1.21 built with Go 1.23 still gets the old behavior. The interviewer wants you to mention the old fix (i := i or passing i as an argument), the go.mod subtlety, and that goroutine print order is never guaranteed.

More on Tricky Output & Code-Review Puzzles

All 38 Tricky Output & Code-Review Puzzles questions