如何同步执行并发初始化切片的go例程?

I am trying to initialize an array of items in concurrently manner using go routines. However, the strange memory behavior of Go prevents me from doing so even I used the suggested primitives (channel). Below is the minimal reproduce:

func TestSliceInit(t *testing.T){
toInit := make([]int, 10)
syncLock := make(chan bool)

for i := range toInit{
    go func(){toInit[i] = i; syncLock <- true}()
}

for range toInit{
    <-syncLock
}

for i := range toInit{
    if toInit[i] != i{
        t.Error("fail to init")
    }
}
}

The code is supposed to initialize the toInit array to 0-9 but it does not. Instead, error will be produced. I tried this code on Goland 2018.1

Because the code is run concurrently, your variable i is modified each time a goroutine is called because they all keep a reference to the same variable i

To prevent that to happen, pass the index parameter to your anonymous function.

package main

import "fmt"

func main() {
  toInit := make([]int, 10)
  syncLock := make(chan bool)

for i := range toInit{
    go func(i int){
      toInit[i] = i; 
      syncLock <- true}(i)
}

for range toInit{
    <-syncLock
}

for i := range toInit{
    if toInit[i] != i{
        fmt.Println("error")
    }
}
}

The other way would be to use a declaration style using the following

for i := range toInit{
        i := i
        go func(){
          toInit[i] = i; 
          syncLock <- true}()
 }

Here is a nice documentation about closures and goroutines