Kodėl negalima paimti nuorodą į reikšmę, saugomą pagal raktą žemėlapyje?
sobes.tech AI
Atsakymas iš AI
Golang'e, žemėlapis (map) yra žodynas, kuris atlieka maišos lentelės funkciją. Pridėti ar pašalinti elementus gali sukelti vidinės žemėlapio struktūros pokyčius, įskaitant atminties paskirstymo peržiūrą ir elementų perkėlimą. Jei paimsite nuorodą į reikšmę, saugomą pagal raktą, ir vėliau pakeisite žemėlapį (pavyzdžiui, pridėdami arba pašalindami kitą elementą), ši nuoroda gali tapti nebegaliojančia, nurodydama į netinkamą atminties sritį arba kitą reikšmę. Golang tai užkerta kelią kompiliacijos metu, draudžiant paimti žemėlapio elemento adresą.
Be to, Golang žemėlapis nėra saugus kelių gijų (thread-safe). Tiesioginis reikšmės keitimas per nuorodą gali sukelti lenktynių sąlygą, jei keli gorutinai prieina prie jos vienu metu, kas apsunkina sinchronizaciją. Draudimas paimti nuorodą į reikšmę žemėlapyje supaprastina prieigos modelį ir aiškiai nurodo sinchronizacijos mechanizmų (pvz., sync.RWMutex) poreikį dirbant su žemėlapiais daugiasriegiuose aplinkose.
Norint pakeisti reikšmę pagal raktą, reikia gauti reikšmę, ją pakeisti ir vėl įrašyti į žemėlapį:
package main
import "fmt"
func main() {
m := map[string]int{"a": 1}
// Negalima paimti nuorodos į reikšmę žemėlapyje
// ptr := &m["a"] // Kompiliacijos klaida
// Teisingas būdas pakeisti reikšmę:
value := m["a"] // Gauti reikšmę
value++ // Pakeisti
m["a"] = value // Įrašyti atgal
fmt.Println(m["a"]) // Išves 2
}