Sobes.tech
Middle

Kāpēc nevar ņemt atsauci uz vērtību, kas ir saglabāta pēc atslēgas kartē?

sobes.tech AI

Atbilde no AI

Golang kartējs (map) pārstāv haštabulu. Elementu pievienošana vai dzēšana var novest pie iekšējās struktūras izmaiņām, tostarp atmiņas sadalījuma pārplānošanas un elementu pārvietošanas. Ja ņem norādi uz vērtību, kas ir saglabāta pēc atslēgas, un pēc tam maina karti (piemēram, pievienojot vai dzēšot citu elementu), šī norāde var kļūt nederīga, norādot uz nepareizu atmiņas apgabalu vai citu vērtību. Golang to novērš kompilācijas laikā, aizliedzot ņemt kartes elementa adresi.

Turklāt, Golang kartes nav drošas vairāku pavedienu (thread-safe). Tieša vērtības maiņa caur norādi var novest pie sacensību stāvokļa, ja vairākas gorutīnas piekļūst tai paralēli, kas sarežģī sinhronizāciju. Aizliegums ņemt norādi uz vērtību kartē vienkāršo piekļuves modeli un skaidri norāda uz nepieciešamību izmantot sinhronizācijas mehānismus (piemēram, sync.RWMutex) darbā ar kartēm daudzšēriju vidē.

Lai mainītu vērtību pēc atslēgas, ir jāiegūst vērtība, jāmaina tā un jāuzglabā atpakaļ kartē:

package main

import "fmt"

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

	// Nav atļauts ņemt norādi uz vērtību kartē
	// ptr := &m["a"] // Kompilācijas kļūda

	// Pareizais veids, kā mainīt vērtību:
	value := m["a"] // Iegūt vērtību
	value++         // Mainīt
	m["a"] = value  // Saglabāt atpakaļ

	fmt.Println(m["a"]) // Izvadīs 2
}