Map-uri în Go
Un map stochează date asociind chei cu valori, iar fiecare element este o pereche cheie:valoare.
Elementele nu au o ordine fixă, le poți modifica liber, iar aceeași cheie nu poate apărea de două ori.
Pentru a afla câte elemente are un map, adică lungimea lui, apelează len().
Un map care nu a fost inițializat are valoarea nil.
În spate, un map păstrează referințe către un tabel hash.
Go îți oferă mai multe moduri de a crea un map, iar secțiunile următoare le parcurg.
Crearea map-urilor folosind var și :=
Atât cuvântul cheie var, cât și operatorul de declarare scurtă := pot fi folosite pentru a crea un map cu valori inițiale.
Notă: Nu te aștepta ca un map să păstreze ordinea pe care ai scris-o în cod. Go aranjează datele stocate în felul său, astfel încât căutarea valorilor să rămână rapidă.
Exemplu
Ieșire: Program Go și ieșirea capturată
package main
import ("fmt")
func main() {
var a = map[string]string{"brand": "Ford", "model": "Mustang", "year": "1964"}
b := map[string]int{"Oslo": 1, "Bergen": 2, "Trondheim": 3, "Stavanger": 4}
fmt.Printf("a\t%v\n", a)
fmt.Printf("b\t%v\n", b)
}
Sintaxa map cu var și :=
var a = map[KeyType]ValueType{key1:value1, key2:value2,...}
b := map[KeyType]ValueType{key1:value1, key2:value2,...}
Crearea map-urilor folosind funcția make()
Funcția make() este o altă opțiune. Îți dă un map pe care îl poți completa apoi câte o cheie pe rând.
Exemplu
Ieșire: Program Go și ieșirea capturată
package main
import ("fmt")
func main() {
var a = make(map[string]string)
a["brand"] = "Ford"
a["model"] = "Mustang"
a["year"] = "1964"
b := make(map[string]int)
b["Oslo"] = 1
b["Bergen"] = 2
b["Trondheim"] = 3
b["Stavanger"] = 4
fmt.Printf("a\t%v\n", a)
fmt.Printf("b\t%v\n", b)
}
Sintaxa map cu make
var a = make(map[KeyType]ValueType)
b := make(map[KeyType]ValueType)
Crearea unui map gol
Un map gol poate fi obținut cu funcția make() sau cu o declarație var fără valoare inițială.
Notă: Doar prima variantă este gata de folosit, așa că make() este cea pe care trebuie să o alegi. Varianta cu var este nil, așa cum arată ieșirea, iar scrierea în ea provoacă un panic la rulare.
Exemplu
Ieșire: Program Go și ieșirea capturată
package main
import ("fmt")
func main() {
var a = make(map[string]string)
var b map[string]string
fmt.Println(a == nil)
fmt.Println(b == nil)
}
Tipuri de chei permise
O cheie poate folosi orice tip care suportă operatorul de egalitate (==), deoarece Go trebuie să poată compara cheile. Asta include:
- Booleeni
- Numere
- String-uri
- Array-uri
- Pointeri
- Struct-uri
- Interfețe (cu condiția ca tipul dinamic să poată fi comparat pentru egalitate)
Trei tipuri nu pot fi chei:
- Slice-uri
- Map-uri
- Funcții
Motivul este că == nu este definit pentru niciunul dintre ele.
Tipuri de valori permise
Valorile nu au o astfel de limită: un map poate stoca valori de orice tip.
Accesarea elementelor unui map
Pentru a citi un element, pune cheia lui între paranteze pătrate după numele map-ului.
Exemplu
Ieșire: Program Go și ieșirea capturată
package main
import ("fmt")
func main() {
var a = make(map[string]string)
a["brand"] = "Ford"
a["model"] = "Mustang"
a["year"] = "1964"
fmt.Printf(a["brand"])
}
Sintaxa de accesare a map-ului
value = map_name[key]
Actualizarea și adăugarea elementelor unui map
Atribuirea unei valori unei chei face două lucruri. Dacă cheia există deja, valoarea ei este actualizată; dacă nu, se adaugă un element nou.
Exemplu
Ieșire: Program Go și ieșirea capturată
package main
import ("fmt")
func main() {
var a = make(map[string]string)
a["brand"] = "Ford"
a["model"] = "Mustang"
a["year"] = "1964"
fmt.Println(a)
a["year"] = "1970"
a["color"] = "red"
fmt.Println(a)
}
Sintaxa de actualizare a map-ului
map_name[key] = value
Eliminarea unui element din map
Apelează funcția delete() cu map-ul și o cheie pentru a elimina acel element.
Exemplu
Ieșire: Program Go și ieșirea capturată
package main
import ("fmt")
func main() {
var a = make(map[string]string)
a["brand"] = "Ford"
a["model"] = "Mustang"
a["year"] = "1964"
fmt.Println(a)
delete(a, "year")
fmt.Println(a)
}
Sintaxa de ștergere din map
delete(map_name, key)
Verificarea existenței unor elemente într-un map
Căutarea unei chei poate returna două valori, de unde vine modelul val, ok. ok îți spune dacă cheia există, chiar și atunci când valoarea ei este goală, cum se întâmplă cu day în exemplu.
Când te interesează doar dacă există cheia, pune identificatorul gol (_) în locul lui val.
Exemplu
Ieșire: Program Go și ieșirea capturată
package main
import ("fmt")
func main() {
var a = map[string]string{"brand": "Ford", "model": "Mustang", "year": "1964", "day": ""}
val1, ok1 := a["brand"]
val2, ok2 := a["color"]
val3, ok3 := a["day"]
_, ok4 := a["model"]
fmt.Println(val1, ok1)
fmt.Println(val2, ok2)
fmt.Println(val3, ok3)
fmt.Println(ok4)
}
Sintaxa de verificare a map-ului
val, ok := map_name[key]
Map-urile sunt referințe
O variabilă de tip map se referă la un tabel hash, nu conține datele în sine.
Așadar, când două variabile indică același tabel hash, o modificare făcută prin oricare dintre ele este vizibilă și prin cealaltă.
Exemplu
Ieșire: Program Go și ieșirea capturată
package main
import ("fmt")
func main() {
var a = map[string]string{"brand": "Ford", "model": "Mustang", "year": "1964"}
b := a
fmt.Println(a)
fmt.Println(b)
b["year"] = "1970"
fmt.Println("După modificarea lui b:")
fmt.Println(a)
fmt.Println(b)
}
Iterarea peste map-uri
O buclă range parcurge fiecare cheie și valoare dintr-un map. Nu te baza pe ordine, deoarece aceasta se poate schimba de la o rulare la alta.
Exemplu
Ieșire: Program Go și ieșirea capturată
package main
import ("fmt")
func main() {
a := map[string]int{"one": 1, "two": 2, "three": 3, "four": 4}
for k, v := range a {
fmt.Printf("%v : %v, ", k, v)
}
}
Iterarea peste map-uri într-o ordine specifică
Un map nu are o ordine proprie. Pentru a-i parcurge elementele într-o anumită succesiune, păstrează acea succesiune într-o altă structură de date, cum ar fi un slice de chei, și parcurge-o pe aceea.
Exemplu
Ieșire: Program Go și ieșirea capturată
package main
import ("fmt")
func main() {
a := map[string]int{"one": 1, "two": 2, "three": 3, "four": 4}
var b []string
b = append(b, "one", "two", "three", "four")
for k, v := range a {
fmt.Printf("%v : %v, ", k, v)
}
fmt.Println()
for _, element := range b {
fmt.Printf("%v : %v, ", element, a[element])
}
}