-1

I am switching from Python to GoLang. I was learning goroutines. I faced strange outputs when I used the goroutines in for loop.

package main

import "fmt"

func main() {
    var test = []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
        28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}
    for _, x := range test{
        go func() {
            fmt.Println(x)
        }()
    }
}

the output:

25
19
28
19
40
40
6

I was thinking it was capturing values from for loop but, when I saw it was increasing and decreasing. I got confused. Why is that happening?

  • 2
    See also https://github.com/golang/go/wiki/CommonMistakes#using-reference-to-loop-iterator-variable – Marc Oct 10 '20 at 08:33
  • 1
    @Marc I don't think that question is a very accurate duplicate. It does have some overlap in that both questions are about the scope and lifetime of the variable in the for loop, but the goroutine version doesn't explicitly use the address-of operator, and it's not obvious (if you don't already know a fair bit about the language) that goroutines don't make a copy of stack variables when they're created. Probably there's a better duplicate though, since this is such a common problem. – Paul Hankin Oct 10 '20 at 08:48

1 Answers1

3

The goroutines are accessing the x variable that is changing in parallel with the execution of the goroutines. This is a common problem encountered by I think even go programmer at least once. You can capture the current value of the variable like this:

for _, x := range test{
    go func(x int) {
        fmt.Println(x)
    }(x)
 }

Or like this:

for _, x := range test{
    x2 := x
    go func() {
        fmt.Println(x2)
    }()
 }
Paul Hankin
  • 54,811
  • 11
  • 92
  • 118