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-ին որպես պարամետր անանուն ֆունկցիային, ինչը ապահովում է արժեքի ճիշտ բռնումը։