for循環+goroutine的坑 (Golang中Routine闭包中的一个坑/協程引用迴圈變數的問題)
func testRoutine() { //Golang中Routine闭包中的一个坑
for i := 0; i < 100; i++ {
go func() { //这是因为很有可能当 for-loop 执行完之后 goroutine 才开始执行,这个时候 val 的值指向切片中最后一个元素。
fmt.Println(i) //值可能是0-100中的任意数字的,有一些可能会重复出现-->引用传递(同一个对象)给了子协程
}()
}
time.Sleep(1 * time.Second)
}
func testRoutineFix2() {
for i := 0; i < 100; i++ {
go func(ii int) {
fmt.Println(ii)
}(i) //参数都是通过值传递进行传递的
}
time.Sleep(1 * time.Second)
}
func testRoutineFix3() {
for i := 0; i < 100; i++ {
ii := i
go func() {
fmt.Println("testRoutineFix3",ii)
}()
}
time.Sleep(1 * time.Second)
}
完整程式碼
https://github.com/minilabmemo/go-my-playground/blob/main/2.gorountine/2.for-go/main.go
結果:
testRoutine 3
testRoutine 10
testRoutine 10
testRoutine 10
testRoutine 10
testRoutine 10
testRoutine 10
testRoutine 10
testRoutine 10
testRoutine 10
testRoutineFix1 0
testRoutineFix1 9
testRoutineFix1 1
testRoutineFix1 6
testRoutineFix1 7
testRoutineFix1 8
testRoutineFix1 3
testRoutineFix1 2
testRoutineFix1 4
testRoutineFix1 5
testRoutineFix2 0
testRoutineFix2 4
testRoutineFix2 1
testRoutineFix2 3
testRoutineFix2 6
testRoutineFix2 7
testRoutineFix2 9
testRoutineFix2 2
testRoutineFix2 8
testRoutineFix2 5
testRoutineFix3 0
testRoutineFix3 1
testRoutineFix3 2
testRoutineFix3 3
testRoutineFix3 9
testRoutineFix3 4
testRoutineFix3 5
testRoutineFix3 6
testRoutineFix3 7
testRoutineFix3 8