Una delle forme di strutture dati più comuni in ogni linguaggio è rappresentata dalle cosiddette associazioni chiave/valore che prevedono
la classificazione di oggetti sfruttando una chiave univoca che ne permetta il riconoscimento. In Go, sono fornite dalle Map ma chi
proviene da altre esperienze di programmazione ritroverà i concetti già visti con le HashMap di Java,
i dizionari Python o gli array associativi di PHP tanto per fare qualche esempio.
Le Map possono essere impiegate in molti casi ed in particolare quando:
- si individua un'univocità tra un oggetto ed una chiave (il reddito di un contribuente ed il suo codice fiscale, la matricola di uno
studente e la sua pagella, etc.); - si vuole accelerare una particolare tipologia di ricerca in base al valore indicato come chiave;
- si vuole creare una struttura dati di appoggio che mediante la chiave permetta di indirizzare velocemente degli oggetti.
Creare Map in Go
Passando alla pratica vediamo subito come può essere creata una Map in linguaggio Go. Come esempio, scegliamo la realizzazione di una
pagella scolastica. E' adeguata una Map in questo caso? Secondo i criteri che abbiamo espresso prima, sì. In fin dei conti, una pagella è costituita
da una serie di accoppiate formate da nome della materia e voto. Uno dei due - il nome della materia - può svolgere il ruolo di chiave in quanto
è univoca: non esistono in una stessa pagella due materie con lo stesso nome. Inoltre, una struttura del genere potrebbe facilitare le ricerche. Se infatti
volessimo recuperare il voto di una sola materia potremmo cercarlo semplicemente per chiave.
Ecco la nostra pagella in Go:
pagella := make(map[string]int)
Con la parola chiave make
abbiamo creato il nostro oggetto specificando tramite l'argomento che la chiave sarà di tipo
string
ed il valore di tipo int
. Per inserirvi dei valori possiamo procedere con una notazione in cui indicheremo
tra parentesi quadre la chiave e assegneremo mediante il simbolo uguale (=) il nuovo valore. Immettiamo un pò di voti nella pagella che
attualmente è vuota:
pagella["Italiano"] = 7
pagella["Storia"] = 8
pagella["Geografia"] = 6
pagella["Matematica"] = 5
pagella["Fisica"] = 6
Abbiamo inserito cinque materie identificate ognuna da una chiave (le chiavi sono le stringhe "Italiano", "Storia", "Geografia", etc.) e corrispondenti ognuna
ad un valore che rappresenta il voto nella specifica materia.
Ottenere informazioni da una Map
Possiamo direttamente farci dire quanti sono gli elementi all'interno della Map pagella
con:
fmt.Println("La pagella contiene ", len(pagella), " materie")
ottenendo in output il messaggio La pagella contiene 5 materie. Per fare ciò abbiamo sfruttato la funzione len
mentre
per produrre l'output ci siamo basati sul package fmt
importato come già visto in precedenza.
Se invece volessimo vedere effettivamente il contenuto totale di una Map potremmo, a scopo di debug, mandarla semplicemente in output con una normale operazione
di Println
:
fmt.Println("Stampa pagella:", pagella)
il che produrrebbe il seguente messaggio: Stampa pagella: map[Fisica:6 Geografia:6 Italiano:7 Matematica:5 Storia:8].
Quanto ottenuto mostra in maniera sintetica proprio l'associazione esistente tra una chiave ("Fisica", ad esempio) ed un voto (6 in questo caso). Si noti però che le materie non
vengono indicate nello stesso ordine dell'inserimento infatti, allo scopo di una memorizzazione efficiente, la Map immagazzina i valori trascurando la sequenza di immissione ma puntando solo
all'ottimizzazione del loro recupero.
Se volessimo estrarre istantaneamente un valore dalla Map relativo ad una specifica chiave senza esperire ricerche prolungate basterebbe impiegare nuovamente
le parentesi quadre, proprio così:
voto_storia := pagella["Storia"]
fmt.Println("In Storia hai preso ", voto_storia)
Modifica di una Map
Una volta popolata, una Map, può essere ancora modificata. Potremmo, ad esempio, procedere ad un inserimento nella pagella associando un nuovo voto
ad una materia:
pagella["Educazione fisica"] = 9
ottenendo di conseguenza messaggi aggiornati con le direttive che abbiamo visto nel paragrafo precedente:
fmt.Println("Stampa pagella:", pagella)
fmt.Println("La pagella contiene ", len(pagella), " materie")
fmt.Println("In Educazione fisica hai ottenuto ", pagella["Educazione fisica"])
che produrrebbero il seguente output:
Stampa pagella: map[Educazione fisica:9 Fisica:6 Geografia:6 Italiano:7 Matematica:5 Storia:8]
La pagella contiene 6 materie
In Educazione fisica hai ottenuto 9
Un valore interno ad una Map può anche essere cancellato utilizzando delete
. Se, ad esempio, volessimo rimuovere il voto
in Geografia potremmo agire nel seguente modo:
delete(pagella, "Geografia")
indicando che dalla struttura pagella
(primo argomento) andremo ad eleminare l'accoppiata chiave/valore identificata
dalla chiave Geografia
, il secondo argomento. La dimostrazione dell'avvenuta rimozione si può ottenere come già fatto:
fmt.Println("Stampa pagella:", pagella)
ricevendo per risposta Stampa pagella: map[Educazione fisica:9 Fisica:6 Italiano:7 Matematica:5 Storia:8] dove non appare
più il voto di Geografia.