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 AI

Odpověď od AI

V tomto kódu je klasická chyba uzávěru v cyklu při práci s gorutinami a ukazateli.

Proměnná i v cyklu se mění, a do pole nums jsou přidávány ukazatele na stejnou proměnnou i. Výsledkem je, že všechny prvky nums ukazují na stejné místo v paměti, které po dokončení cyklu obsahuje hodnotu 9.

Při spuštění gorutin všechny budou tisknout stejnou hodnotu — adresa, na kterou ukazuje v, bude stejná pro všechny prvky.

Chcete-li to opravit, je třeba uvnitř cyklu vytvořit novou proměnnou, aby každý ukazatel ukazoval na odlišnou hodnotu:

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)
    }
}

Zde vytváříme val uvnitř cyklu a předáváme v jako parametr do anonymní funkce, což zajišťuje správné zachycení hodnoty.