Pourquoi les Maps ?
Go fournit un autre type de données important nommé Map, qui associe des clés uniques à des valeurs.
Avant pour récupérer un élément précis dans votre tableau vous utilisiez un index, les Maps possèdent le même processus de récupération d’éléments qu’un tableau cependant pour les Maps votre index est nommé clé et votre clé peut être de n’importe quel type (int, string, float64 …) à l'instar des tableaux où l’index est obligatoirement de type int.
Par exemple on peut créer une Map avec comme clé les noms des élèves et comme valeur leurs notes et intercepter la note d’un élève précis (la valeur) en utilisant son nom (la clé)
Déclarer une Map
Comme les Slices, il existe deux façons pour créer une Map.
Première méthode :
package main
import (
"fmt"
)
func main() {
var notes map[string]int
}
Deuxième méthode depuis la fonction make()
package main
import (
"fmt"
)
func main() {
var notes = make(map[string]int)
}
Comme dans d'autres types de variables il est aussi possible de surcharger les valeurs par défaut de votre Map.
package main
import "fmt"
func main() {
notes := map[string]int{"Hatim": 20, "Alex": 18}
fmt.Println(notes)
}
Résultat :
map[Alex:18 Hatim:20]
Rajouter un élément dans une Map
Voici comment on rajoute un élément dans une Map.
package main
import "fmt"
func main() {
var notes = make(map[string]int)
notes["Hatim"] = 20
notes["Alex"] = 18
notes["Kevin"] = 15
fmt.Println(notes)
}
Résultat :
map[Alex:18 Hatim:20 Kevin:15]
Récupérer les éléments d'une Map
Récupérer un élément précis
Comme expliqué sur l'introduction de ce chapitre, on récupère un élément d'une Map grâce à sa clé, donc on utilisera la clé de l'élément de notre Map pour récupérer sa valeur.
package main
import "fmt"
func main() {
notes := map[string]int{"Hatim": 20, "Alex": 18}
fmt.Println("La note de Hatim est :", notes["Hatim"])
fmt.Println("La note de Alex est :", notes["Alex"])
}
Résultat :
La note de Hatim est : 20
La note de Alex est : 18
Boucle for dans une map
On peut utiliser la boucle for avec le mot-clé range pour récupérer la clé de tous les éléments de votre Map.
package main
import "fmt"
func main() {
notes := map[string]int{"Hatim": 20, "Alex": 18, "Kevin": 15, "Robert": 17}
for eleve := range notes {
fmt.Println("La note de ", eleve, "est", notes[eleve])
}
}
Résultat :
La note de Hatim est 20
La note de Alex est 18
La note de Kevin est 15
La note de Robert est 17
Supprimer un élément dans une Map
Pour supprimer un élément de votre Map il faut utiliser la fonction delete(), qui prend comme paramètres d'abord votre Map et ensuite la clé de l'élément que vous voulez supprimer.
package main
import "fmt"
func main() {
notes := map[string]int{"Hatim": 20, "Alex": 18, "Kevin": 15, "Robert": 17}
fmt.Println(notes)
delete(notes, "Hatim")
fmt.Println(notes)
}
Résultat :
map[Alex:18 Hatim:20 Kevin:15 Robert:17]
map[Alex:18 Kevin:15 Robert:17]
Espace commentaire
Écrire un commentaire
Rejoignez la discussion
Vous devez être connecté pour poster un message.
24 commentaires
Pensez à bien définir la capacité initiale avec
make(map[string]int, 1000)si vous connaissez la taille, ça évite les réallocations coûteuses.Ta RAM est la seule limite réelle. Par contre, plus elle est grande, plus le GC va ramer lors du scan.
Il y a une limite de taille pour les maps ?
Oui, les maps sont des types référence. Tu modifies la map originale, pas une copie.
Si je passe une map à une fonction, les modifs sont persistantes ?
Absolument pas. Si tu as des accès concurrents, utilise un
sync.RWMutexou unsync.Map.C'est thread-safe les maps en Go ?
Go ne permet pas de trier une map nativement. Tu dois extraire les clés dans un slice, trier le slice, puis itérer.
J'ai besoin de trier ma map par clé, vous faites comment ?
Exact, c'est une opération no-op. Ça ne panique pas, c'est safe.
Le
delete()ne fait rien si la clé n'existe pas ?Tu peux ignorer la valeur avec
_:Quelqu'un peut me donner un exemple de
rangepropre pour récupérer juste les clés ?delete()supprime l'entrée, mais la capacité allouée reste. Si la map est vraiment trop grosse, le mieux est de la réassigner ànilpour que le GC fasse le taff.J'ai une map énorme et je veux libérer la mémoire.
delete()suffit ou il faut faire autre chose ?Non, c'est voulu. Go randomise l'ordre d'itération des maps pour éviter que tu ne comptes dessus.
Ne jamais supposer un ordre de sortie en prod.
La boucle
for rangeest bien pratique mais l'ordre d'itération me semble aléatoire. C'est un bug ?Les slices ne sont pas comparables. Une clé de map doit supporter l'opérateur
==.Pour les structs, ça marche seulement si tous les champs à l'intérieur sont eux-mêmes comparables.
J'ai testé avec un slice en clé et le compilateur m'a envoyé bouler. Pourquoi ?
Est-ce qu'on peut utiliser une struct comme clé ?
Utilise l'idiome
val, ok := notes[key]. Siokest false, la clé n'existe pas.Comment on fait pour vérifier si une clé existe vraiment dans la map sans récupérer une valeur par défaut ?
C'est normal, tu as déclaré une map nil. Elle n'est pas initialisée.
Utilise
make()avant d'assigner des valeurs, sinon tu écris dans le vide.J'essaie de déclarer ma map avec
var notes map[string]intmais quand je fais unnotes["test"] = 10, ça me balance un panic runtime. C'est normal ?