Sobes.tech
Senior

1.21 func main() { var nums []*int for i := 0; i < 10; i++ { nums = append(nums, &i) } for _, v := range nums { go func() { fmt.Println(v) }() } }

sobes.tech MI

Válasz az MI-től

Ebben a kódban egy klasszikus zárási hiba van a ciklusban, amikor goroutine-okat és pointereket használunk.

A i változó a ciklus során változik, és a nums szelethez ugyanarra a i változóra mutató pointereket adunk hozzá. Ennek eredményeként minden nums elem ugyanarra a memóriahelyre mutat, amely a ciklus befejezése után az értéket 9 tartalmazza.

Amikor a goroutine-ok elindulnak, mind ugyanazt az értéket fogják kiírni — a v által mutatott cím minden elem esetében ugyanaz lesz.

A javításhoz a cikluson belül létre kell hozni egy új változót, hogy minden pointer egy külön értékre mutasson:

func main() {
    var nums []*int
    for i := 0; i < 10; i++ {
        val := i
        nums = append(nums, &val)
    }

    for _, v := range nums {
        go func(v *int) {
            fmt.Println(*v)
        }(v)
    }
}

Itt a cikluson belül létrehozzuk a val-t, és átadjuk a v-t paraméterként egy anonim függvénynek, ami biztosítja a helyes értékfogást.