Understanding the Unexpected Behavior of Go Concurrency with For Loops and Anonymous Functions
In Go, when using a for loop to create goroutines with anonymous functions, an unexpected behavior can arise, resulting in all goroutines printing the same value. To comprehend this behavior, let's analyze the following code:
func main() { var wg sync.WaitGroup for i := 1; i <= 5; i++ { wg.Add(1) go func() { fmt.Println(i) time.Sleep(time.Second * 1) wg.Done() }() } wg.Wait() }
Surprisingly, this code prints "6, 6, 6, 6, 6," instead of the expected "2, 4, 1, 5, 3." This anomaly is attributed to the closures created by anonymous functions.
In Go, closures are functions that capture variables from their surrounding scope. In the code above, each anonymous function captures the variable i. However, when the for loop iterates, i is already at 5. This means that all the closures capture the same value of i, which is 6.
To solve this issue, we can pass i as an argument to the anonymous function. By doing so, we create a local copy of i that is captured by each closure, ensuring that each goroutine prints the correct value:
func main() { var wg sync.WaitGroup for i := 1; i <= 5; i++ { wg.Add(1) go func(i int) { fmt.Println(i) time.Sleep(time.Second * 1) wg.Done() }(i) } wg.Wait() }
The above is the detailed content of Why Do Go Concurrency Loops with Anonymous Functions Print the Same Value?. For more information, please follow other related articles on the PHP Chinese website!