为什么局部变量在goroutine中的匿名函数中是不同的参数

package main

import (
  "fmt"
  "runtime"
)

func main() {
  runtime.GOMAXPROCS(runtime.NumCPU())
  fmt.Println(runtime.GOMAXPROCS(0))

  // s := "hello world 
"

  for i := 0; i < 100; i++ {
    go func(n int) {
        fmt.Println(n, i)
    }(i)
  }

  fmt.Scanln()
}

I just wondering why n is not equal to i every go routine.

Also i sometimes has the same value as in the previous call.

What is the matter in this code?

This topic is well covered (across multiple languages) - but the short version is this:

Your current output is like this:

1 100
2 100
3 100
4 100
...

The variable i becomes part of a closure. This means that its value actually outlasts its scope (its moved off to the side so that when the goroutine executes it knows where to find i).

By the time the scheduler gets around to executing your goroutines, the for loop has finished and the value of i is going to be 100 (or close to it if you're running on a slow machine).

The fix is to store the value every iteration and use that:

for i := 0; i < 100; i++ {
    x := i            // <------ Store the value of i each loop iteration
    go func(n int) {
        fmt.Println(n, x) // <---- Use the new, local, closed over value, not the main closed over one
    }(i)
} 

Now every goroutine references its own copy of a closed over variable x, and your output becomes:

1 1
2 2
3 3
4 4
...

This phenomenon is not isolated to Go.

You can see a working sample on the playground: View it on the Playground