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
Απάντηση από AI
Σε αυτόν τον κώδικα υπάρχει ένα κλασικό σφάλμα κλεισίματος στον βρόχο κατά την εργασία με goroutines και δείκτες.
Η μεταβλητή i στον βρόχο αλλάζει, και στη λίστα nums προστίθενται δείκτες στην ίδια μεταβλητή i. Ως αποτέλεσμα, όλα τα στοιχεία του nums δείχνουν στην ίδια θέση μνήμης, η οποία μετά το τέλος του βρόχου περιέχει την τιμή 9.
Όταν ξεκινούν οι goroutines, θα εκτυπώνουν όλες την ίδια τιμή — η διεύθυνση στην οποία δείχνει το v θα είναι η ίδια για όλα τα στοιχεία.
Για να διορθωθεί αυτό, πρέπει να δημιουργήσετε μια νέα μεταβλητή μέσα στον βρόχο, ώστε κάθε δείκτης να δείχνει σε μια ξεχωριστή τιμή:
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)
}
}
Εδώ δημιουργούμε το val μέσα στον βρόχο και περνάμε το v ως παράμετρο σε μια ανώνυμη συνάρτηση, που εγγυάται μια σωστή σύλληψη της τιμής.