Golang / GoLang Concurrency Mastery Interview Questions
What is the goroutine loop-variable capture bug and how do you fix it?
One of the most common Go concurrency interview puzzles. When a goroutine closure captures a loop variable by reference, all goroutines in the loop share the same variable — which has already advanced to its final value by the time any goroutine runs.
// BUG (Go 1.21 and earlier): all goroutines may print 5 for i := 0; i < 5; i++ { go func() { fmt.Println(i) // captures &i â reads whatever i is RIGHT NOW }() } // By the time goroutines execute, the loop finished and i == 5 // Typical output: 5 5 5 5 5 // FIX 1: pass as argument â creates an independent copy per iteration for i := 0; i < 5; i++ { go func(n int) { // n is a local copy of i at this point fmt.Println(n) // 0 1 2 3 4 (in any order) }(i) } // FIX 2: shadow the loop variable inside the loop body for i := 0; i < 5; i++ { i := i // new variable, shadows the outer i go func() { fmt.Println(i) }() } // GO 1.22+: loop variables are per-iteration by default // for i := range 5 { go func() { fmt.Println(i) }() } // safe in 1.22! // Same bug with range over slice names := []string{"Alice", "Bob", "Carol"} for _, name := range names { go func() { fmt.Println(name) }() // BUG: all may print "Carol" } // Fix for _, name := range names { go func(n string) { fmt.Println(n) }(name) }
More Related questions...