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

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