Ma

Mapok ebben a kurzusban: Go

2 feladat

A(z) Mapok fogalomról

A Go-ban a map egy beépített adattípus, amely egy hash-táblát képvisel. Más programozási nyelvekben a mapot dict néven, asszociatív tömbként vagy kulcs-érték tárolóként ismerheted. Ha még nem találkoztál ezzel a fogalommal, gondolhatsz a map-re úgy, mint egy szótárra, amelyben minden szó a key, a definíció pedig a map element-je.

Mielőtt elkezdjük, szeretném felhívni a figyelmedet a map Go-specifikációjára és a mapról szóló Go blogbejegyzésre, hogy mélyebben elmerülhess a map-ben.

Szintaktikailag a map így néz ki:

map[KeyType]ElementType

A KeyType-nak összehasonlítható típusnak kell lennie, az ElementType viszont bármilyen érvényes Go-típus lehet, ami azt jelenti, hogy bármit tárolhatsz benne egy primitív változótól egy szeletig.

Fontos megjegyezni, hogy a Go-ban a map nem rendezett. Ha végigmész egy map-en, és kiíratod az elemeket, meglephet, hogy az elemek véletlenszerű sorrendben jelennek meg (próbáld csak ki, ha kedved tartja).

Az is fontos, hogy minden kulcs egyedi, ami azt jelenti, hogy ha ugyanazt a kulcsot kétszer rendeled hozzá, felülírod a hozzá tartozó kulcs értékét.

A map referenciatípus, ami azt jelenti, hogy ha továbbadod, a Go nem másolja le a teljes mapet. Ehelyett a Go a map mutatóját másolja, ami olcsóvá teszi, hogy egy mapet függvénynek vagy változónak adj át. Egy inicializálatlan map értéke nil.

A mapet a következőképpen definiálhatod (ezt nil map-nek is nevezik):

  var foo map[string]int

Egy map inicializálásához ezt teheted:

  // With map literal
  foo := map[string]int{}

vagy

  // or with make function
  foo := make(map[string]int)

A nil map különbözik egy inicializált maptól: ha egy nil mapbe írsz, futásidejű hiba lesz belőle

panic: assignment to entry in nil map

Ezért fontos, hogy használat előtt inicializáld a mapet

Íme néhány művelet, amit egy mappel végezhetsz

  // Add a value in a map with the `=` operator:
  foo["bar"] = 42
  // Here we update the element of `bar`
  foo["bar"] = 73
  // To retrieve a map value, you can use
  baz := foo["bar"]
  // To delete an item from a map, you can use
  delete(foo, "bar")

Ha olyan kulcs értékét próbálod lekérdezni, amely nem létezik a mapben, az az értéktípus nullértékét adja vissza. Ez összezavarhat, különösen akkor, ha az ElementType alapértéke (például egy intnél a 0) egyébként érvényes érték. Ha ellenőrizni szeretnéd, hogy létezik-e egy kulcs a mapben, ezt használhatod:

  value, exists := foo["baz"]
  // If the key "baz" does not exist,
  // value: 0; exists: false

Ahogy korábban láttuk, könnyű eldönteni, hogy egy map inicializálva van-e: egyszerűen összehasonlíthatjuk nil-lel. De mi a helyzet két map összehasonlításával? Mivel a map nem összehasonlítható, a == operátort nem használhatjuk, viszont a reflect csomag segít rajtunk: a DeepEqual nevű függvényt így használhatjuk

import "reflect"

// ....

equal := reflect.DeepEqual(map[string]int{}, map[string]int{})
fmt.Println(equal)
// Output: true

De várjunk csak: ha a map nem összehasonlítható, miért tudjuk mégis összehasonlítani nil-lel? Nos, a spec kivételt tett erre, lásd az összehasonlítható típusok specifikációját

Végül: ha több goroutine-ból próbálsz egy map-be írni, az aktiválja a race detectort, lásd a Go dokumentációt és a Go blogot. Alternatívaként használhatsz sync.Map-et, atomic-ot vagy mutex-et, hogy megkerüld ezt a problémát.

Szerkesztés GitHubon A hivatkozás új ablakban vagy lapon nyílik meg

Tanuld meg a(z) Mapok fogalmat

A gyakorlás zárolva

Oldj fel még 3 feladatot, hogy gyakorolhasd a(z) Mapok fogalmat