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

Бу кодда, горутинлар ва ишорачилар билан ишлашда циклда ёпилишнинг классик хато мавжуд.

Циклдаги i ўзгарувчи ўзгариб туради, ва nums кесимига бир хил i ишорачилари қўшилади. Натижада, nums элементлари барчаси бир хил ёдлаш жойига ишора қилади, ва цикл тугашидан кейин бу жой 9 қийматини сақлайди.

Горутинлар ишга туширилганда, улар ҳаммаси бир хил қийматни чиқаришади — 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 аноним функцияга параметр сифатида ўтказилади, бу эса қийматни тўғри ёпишни таъминлайди.