Understanding For Loop Behavior in Go
In programming, certain constructs can lead to unexpected behavior. Consider these two variations of for loops:
var cmds = []string{"create", "delete", "update"} func loop1() { actions := make(map[string]func()) for _, cmd := range cmds { actions[cmd] = func() { fmt.Println(cmd) } } for _, action := range actions { action() } } func loop2() { actions := make(map[string]func()) for i, cmd := range cmds { command := cmds[i] actions[cmd] = func() { fmt.Println(command) } } for _, action := range actions { action() } }
Loop1 prints "update" three times, while loop2 prints "delete", "update", and "create". To understand this behavior, let's delve into the details.
Loop Variable Reference
In loop1, we declare a loop variable cmd and use it to iterate over the cmds slice. However, within the nested loop, the variable cmd still references the loop variable from the outer loop.
Value Sharing in Closures
When creating the function literals in the map actions, the loop variable cmd is captured by the closures. This means that each function inherits a reference to the same loop variable instance, not a copy.
Last Value Dependency
By the time the nested loop is completed, the loop variable cmd has progressed to the last element in the slice ("update"). This means that all the closures now reference the last element.
Result:
When printing inside the nested loop, all closures print "update" because they all reference the same last element in the slice.
Fix:
To fix this issue, we create a copy of the loop variable in loop1 using cmd2 := cmd and use that copy in the function literals. This ensures each closure has a distinct reference to the value of cmd at the time of its creation.
This clarification highlights the nuance of referencing loop variables within closures and demonstrates the importance of carefully understanding how closures capture variables in Go.
The above is the detailed content of Why Does Loop1 Print 'update' Three Times While Loop2 Prints Different Values in This Go Code Example?. For more information, please follow other related articles on the PHP Chinese website!