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

Odpowiedź od AI

W tym kodzie występuje klasyczny błąd zamknięcia w pętli podczas pracy z gorutynami i wskaźnikami.

Zmienna i w pętli się zmienia, a do tablicy nums dodawane są wskaźniki na tę samą zmienną i. W rezultacie wszystkie elementy nums wskazują na to samo miejsce w pamięci, które po zakończeniu pętli zawiera wartość 9.

Podczas uruchamiania gorutyn będą one wszystkie wypisywać tę samą wartość — adres, na który wskazuje v, będzie taki sam dla wszystkich elementów.

Aby to naprawić, należy tworzyć nową zmienną wewnątrz pętli, tak aby każdy wskaźnik wskazywał na odrębną wartość:

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

Tutaj tworzymy val wewnątrz pętli i przekazujemy v jako parametr do funkcji anonimowej, co gwarantuje poprawne uchwycenie wartości.