Une map en Go est une collection non ordonnée de paires clé/valeur, notée
map[K]V. Elle offre une recherche rapide par clé — la même idée qu’un
dictionnaire en Python ou qu’un objet en JavaScript, mais typée statiquement.
Créer une map
Vous pouvez construire une map à partir d’un littéral ou la créer vide avec la
fonction intégrée make. Dans les deux cas, la map est prête à l’emploi ; les
clés doivent être d’un type comparable comme une chaîne, un entier ou un
booléen.
// Un littéral de map avec deux entrées.
ages := map[string]int{
"Ada": 36,
"Alan": 41,
}
// Une map vide prête à recevoir des écritures, créée avec make.
scores := make(map[string]int)
Lire et écrire des valeurs
Vous écrivez avec m[clé] = valeur et vous lisez avec m[clé]. Une clé absente
ne provoque pas d’erreur : sa lecture renvoie la valeur zéro du type des
valeurs.
scores["Ada"] = 100 // écriture
top := scores["Ada"] // lecture : 100
absente := scores["Bob"] // clé absente : valeur zéro, 0
L’idiome virgule-ok
Comme une clé absente renvoie une valeur zéro, scores["Bob"] == 0 ne permet
pas de savoir si Bob a marqué zéro ou s’il est simplement absent. La forme à
deux valeurs de la lecture règle le problème : la seconde valeur est un booléen
true uniquement lorsque la clé existe.
if score, ok := scores["Bob"]; ok {
fmt.Println("trouvé :", score)
} else {
fmt.Println("Bob n’a pas encore de score")
}
Supprimer des clés et compter avec len
delete retire une clé (et ne fait rien si la clé est absente). len renvoie
le nombre d’entrées.
delete(scores, "Ada") // retire une clé
total := len(scores) // nombre d’entrées restantes
Parcourir une map
Une boucle for ... range visite chaque paire clé/valeur. L’ordre est
volontairement aléatoire, imposé par le runtime : ne vous y fiez jamais. Si
vous avez besoin d’un ordre stable, collectez les clés dans une slice et
triez-les.
for nom, score := range scores {
fmt.Printf("%s -> %d\n", nom, score)
}
Un exemple complet
Le programme ci-dessous compte le nombre d’occurrences de chaque mot d’une phrase. Il trie les clés avant l’affichage pour un résultat déterministe. Il compile et s’exécute tel quel.
package main
import (
"fmt"
"sort"
"strings"
)
func main() {
text := "the quick brown fox the lazy dog the end the fox"
counts := make(map[string]int)
for _, word := range strings.Fields(text) {
counts[word]++
}
// On collecte les clés puis on les trie pour un affichage stable,
// car le parcours d’une map visite les clés dans un ordre aléatoire.
words := make([]string, 0, len(counts))
for word := range counts {
words = append(words, word)
}
sort.Strings(words)
for _, word := range words {
fmt.Printf("%s: %d\n", word, counts[word])
}
}
Son exécution affiche :
brown: 1
dog: 1
end: 1
fox: 2
lazy: 1
quick: 1
the: 4
Les maps sont des types référence
Une valeur de type map est un petit en-tête qui pointe vers les données sous-jacentes. Lorsque vous passez une map à une fonction, les deux côtés partagent le même stockage : les écritures faites dans la fonction sont visibles par l’appelant. C’est pratique, mais cela entraîne deux conséquences à garder en tête.
Erreurs fréquentes
- Écrire dans une map nil. Déclarer
var m map[string]intdonne une map nil. Vous devez la créer avecmakeavant la première écriture. - Se fier à l’ordre du parcours. L’ordre d’itération change à chaque exécution, par conception. Triez les clés lorsque vous voulez un résultat reproductible.
- Confondre absent et zéro. Utilisez la forme virgule-ok plutôt que de comparer la valeur à sa valeur zéro.
- Prendre l’adresse d’une entrée.
&m[clé]est interdit, car le runtime peut déplacer les entrées. Stockez une valeur, modifiez-la, puis réécrivez-la.
À vous de jouer
À partir d’une slice de chaînes de votes, construisez une map de comptes, puis
utilisez l’idiome virgule-ok pour afficher le compte de "go", en affichant
go: 0 s’il n’est jamais apparu.
Afficher la correction
package main
import "fmt"
func main() {
votes := []string{"go", "rust", "go", "python", "go"}
counts := make(map[string]int)
for _, v := range votes {
counts[v]++
}
if n, ok := counts["go"]; ok {
fmt.Printf("go: %d\n", n)
} else {
fmt.Println("go: 0")
}
}Chaque tour de boucle incrémente le compteur du vote courant. La lecture
virgule-ok distingue ensuite un vrai compte d’une clé absente. Ici, le programme
affiche go: 3.
Résumé
- Créez des maps avec un littéral ou
make; les clés doivent être comparables. - Une clé absente se lit comme la valeur zéro ; utilisez la forme virgule-ok pour en avoir le cœur net.
deleteretire une clé,lencompte les entrées, et l’ordre derangeest aléatoire.- Les maps sont des types référence et ne sont pas sûres en écriture concurrente.
Ensuite, apprenez à modéliser des données plus riches avec les structs et les méthodes en Go. Pour revoir d’abord les collections ordonnées, relisez les tableaux et slices.