Miks ei saa võtta viidet väärtusele, mis on salvestatud võtme järgi kaardil?
sobes.tech AI
Vastus AI-lt
Golangis esindab kaardil (map) hajuska tabelit. Elementide lisamine või eemaldamine võib põhjustada kaardi sisemise struktuuri muutusi, sealhulgas mälu ümberjaotamist ja elementide liigutamist. Kui võtate viite väärtusele, mis on salvestatud võtme järgi, ja seejärel muudate kaarti (näiteks lisades või eemaldades teise elemendi), võib see viide muutuda kehtetuks, osutades valele mälu piirkonnale või teisele väärtusele. Golang takistab seda kompileerimise ajal, keelates kaardi elemendi aadressi võtmise.
Lisaks ei ole Golang'i kaart thread-safe. Otseviite kaudu väärtuse muutmine võib põhjustada võistlusolukorra, kui mitu gorutini sellele samaaegselt ligi pääsevad, mis raskendab sünkroniseerimist. Viite võtmise keeld kaardi väärtusele lihtsustab juurdepääsumudelit ja teeb selgeks vajaduse kasutada sünkroniseerimismehhanisme (näiteks sync.RWMutex) mitme lõimega keskkonnas töötamisel.
Väärtuse muutmiseks võtme järgi tuleb esmalt väärtus saada, seda muuta ja seejärel salvestada muudetud väärtus tagasi kaardile:
package main
import "fmt"
func main() {
m := map[string]int{"a": 1}
// Ei ole võimalik võtta viidet kaardi väärtusele
// ptr := &m["a"] // Kompileerimisviga
// Õige viis väärtuse muutmiseks:
value := m["a"] // Väärtuse saamine
value++ // Muutmine
m["a"] = value // Muudetud väärtuse salvestamine
fmt.Println(m["a"]) // Väljund 2
}