Sobes.tech
Middle

რატომ არ შეიძლება ბმული აიღო მნიშვნელობაზე, რომელიც ინახება გასაღებით რუკაში?

sobes.tech AI

პასუხი AI-სგან

Golang-ში, რუკა (map) წარმოადგენს ჰეშ-ცხრილს. ელემენტების დამატება ან წაშლა შეიძლება გამოიწვიოს რუკის შიდა სტრუქტურის ცვლილებები, მათ შორის მეხსიერების გადანაწილება და ელემენტების გადაადგილება. თუ მიიღებთ მაჩვენებელს ღირებულებაზე, რომელიც შენახულია გასაღებით, და შემდეგ შეცვლით რუკას (მაგალითად, დაამატებთ ან წაშლით სხვა ელემენტს), ეს მაჩვენებელი შეიძლება გახდეს გაუქმებული, მიუთითებს არასწორ მეხსიერების ზონაზე ან სხვა მნიშვნელობაზე. Golang ამ პრევენციას ახორციელებს კომპილაციის დროს, აკრძალვით რუკის ელემენტის მისამართის აღებას.

გარდა ამისა, Golang-ის რუკა არ არის თრედ-უსაფრთხო (thread-safe). პირდაპირი ცვლილება მაჩვენებლით შეიძლება გამოიწვიოს შეჯახების მდგომარეობა, თუ სხვადასხვა გორუტინები ერთდროულად მიიჩნევენ მას, რაც სინქრონიზაციას ართულებს. რუკის მნიშვნელობის მაჩვენებლის აღების აკრძალვა ამარტივებს ერთდროულ წვდომის მოდელს და აშკარად აჩვენებს სინქრონიზაციის მექანიზმების (მაგალითად, sync.RWMutex) გამოყენების აუცილებლობას მრავალთრიან გარემოში.

მნიშვნელობის შეცვლისთვის, საჭიროა მნიშვნელობის მიღება, შეცვლა და შემდეგ დაბრუნება რუკაში:

package main

import "fmt"

func main() {
	m := map[string]int{"a": 1}

	// არ შეიძლება მაჩვენებლის აღება რუკის მნიშვნელობაზე
	// ptr := &m["a"] // კომპილაციის შეცდომა

	// სწორი მეთოდი მნიშვნელობის შეცვლის:
	value := m["a"] // მნიშვნელობის მიღება
	value++         // შეცვლა
	m["a"] = value  // დაბრუნება რუკაში

	fmt.Println(m["a"]) // გამოიტანს 2
}