Home >Backend Development >Golang >Why Does Go's `range` Loop Produce Different Results with Varying Loop Structures?

Why Does Go's `range` Loop Produce Different Results with Varying Loop Structures?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-19 18:20:10987browse

Why Does Go's `range` Loop Produce Different Results with Varying Loop Structures?

Understanding the Different Loop Variations in Go

When iterating over a slice in Go, you may encounter unexpected behavior when using the range method. Let's delve into why different loop variations can produce different results.

The Problem

Consider the following two for loop variations:

loop1() {
    for _, cmd := range cmds {
        // Store a function literal that references the loop variable cmd
        actions[cmd] = func() {
            fmt.Println(cmd)
        }
    }
}
loop2() {
    for i, cmd := range cmds {
        // Capture the loop variable cmd using a new variable
        command := cmds[i]
        actions[cmd] = func() {
            fmt.Println(command)
        }
    }
}

Running these loops results in different outputs:

  • loop1(): Prints "update" three times
  • loop2(): Prints "delete", "update", and "create"

The Explanation

The issue with loop1() arises because the function literals that are stored in the actions map reference the loop variable cmd. Since there is only one instance of this loop variable, all functions stored in the map will refer to it.

When the loop completes, the value of cmd will be the last element in the cmds slice, "update." As a result, when the functions in the actions map are executed, they will all print "update."

To circumvent this issue, loop2() captures the loop variable cmd using a new variable, command. This creates a "detached" copy of the loop variable for each iteration, which is not affected by the loop variable after the loop completes.

As a consequence, each function stored in the actions map in loop2() has its own copy of the loop variable, which allows each function to print the correct command.

Conclusion

When ranging over a slice, it's important to be aware that the loop variable is shared among all iterations. To avoid unexpected behavior, it's good practice to capture or detach the loop variable using a new variable, especially when using function literals that will be executed after the loop.

The above is the detailed content of Why Does Go's `range` Loop Produce Different Results with Varying Loop Structures?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn