Consider the following Golang code (also on the Go Playground):
package main
import \"fmt\"
import \"time\"
func main() {
for _, s := range []string{\"
Closures in Go are lexically scoped. This means that any variables referenced within the closure from the "outer" scope are not a copy but are in fact a reference. A for loop actually reuses the same variable multiple times, so you're introducing a race condition between the read/write of the s variable.
But x is allocating a new variable (with the :=) and copying s, which results in that being the correct result every time.
In general, it is a best practice to pass in any arguments you want so that you don't have references. Example:
for _, s := range []string{"foo", "bar"} {
x := s
go func(s string) {
fmt.Printf("s: %s\n", s)
fmt.Printf("x: %s\n", x)
}(s)
}