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
პასუხი AI-სგან
ამ კოდში არსებობს კლასიკური დახურვის შეცდომა ციკლში, როდესაც მუშაობთ goroutine-ებთან და მაჩვენებლებთან.
ციკლში ცვლადი i იცვლება, და სლაის nums ემატება მაჩვენებლები ერთსა და იმავე ცვლადზე i. საბოლოოდ, ყველა ელემენტი nums-ის მიუთითებს ერთსა და იმავე მეხსიერების ადგილას, რომელიც ციკლის დასრულების შემდეგ შეიცავს მნიშვნელობას 9.
როდესაც იწყება goroutine-ები, ისინი ყველა გამოიტანენ ერთსა და იმავე მნიშვნელობას — 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-ს როგორც პარამეტრს ანონიმურ ფუნქციას, რაც უზრუნველყოფს სწორი მნიშვნელობის დაჭერას.