-2

This code:

import "fmt"
import "time"
func main() {
    string_slice:=[]string{"a","b","c"}

    for _,s:=range string_slice{
        go func(){
            time.Sleep(1*time.Second)
            fmt.Println(s)
        }()
    }

    time.Sleep(3*time.Second)
}

produces the output "c c c", while this code:

import "fmt"
func main() {
    string_slice:=[]string{"a","b","c"}

    for _,s:=range string_slice{
        s="asd"
        fmt.Println(s)
    }
    fmt.Println(string_slice)
}

produces the output "[a b c]"

The first one would suggest that for range iterates over references (which it should not), and the second one suggests that it iterates over copies of values (which it should).

Why doesn't the first one produce the output "a b c"?

  • 1
    what's the point of the second one? you're just printing the whole slice after you've printed `"asd"` 3 times. https://play.golang.org/p/rNEGrgS3AT – mkopriva Aug 29 '17 at 14:35
  • 4
    https://github.com/golang/go/wiki/CommonMistakes#using-goroutines-on-loop-iterator-variables –  Aug 29 '17 at 14:36
  • 2
    https://golang.org/doc/faq#closures_and_goroutines – JimB Aug 29 '17 at 14:41

1 Answers1

0

When uses goroutine you must assume that it will running in parallelo. So in this case might occur 'c c c' as too 'b b b' or 'a a a'

On run in 3 times this code:

for _,s:=range string_slice \\run t0, t1, t2 

You will send for running 3 times this code:

go func(){
  fmt.Println(s)
}()//send in t0, t1, t2

So, might occur of func() start running in t2, per example. In this case the result will 'c c c' because s equals latest value (string_slice[2]).

The solution is copy value by func params:

for _, s := range string_slice{
    go func(x string){
        time.Sleep(1*time.Second)
        fmt.Println(x)
    }(s)
}

Or create new value per iteration

//creating new value per iteration
for i := range string_slice{
    s := string_slice[i]
    go func(){
        time.Sleep(1*time.Second)
        fmt.Println(s)
    }()
}

See working in https://play.golang.org/p/uRD6Qy6xSw

Aristofanio Garcia
  • 1,103
  • 8
  • 13