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-ს როგორც პარამეტრს ანონიმურ ფუნქციას, რაც უზრუნველყოფს სწორი მნიშვნელობის დაჭერას.