Les Maps dans le langage de programmation Go

Ce chapitre vous explique les Maps en GoLang. Elles permettent d'associer des clés uniques à des valeurs. Vous allez apprendre à déclarer une Map et à récupérer, rajouter, modifier et supprimer les éléments d'une Map dans le langage de programmation Go.

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

ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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.

04/04/2019 à 19:24
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Ta RAM est la seule limite réelle. Par contre, plus elle est grande, plus le GC va ramer lors du scan.

04/04/2019 à 11:48
alexandria30
Membre Actif
Avatar de alexandria30
alexandria30
Membre Actif

Il y a une limite de taille pour les maps ?

04/04/2019 à 05:41
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Oui, les maps sont des types référence. Tu modifies la map originale, pas une copie.

03/04/2019 à 23:07
pmarchand
Membre Actif
Avatar de pmarchand
pmarchand
Membre Actif

Si je passe une map à une fonction, les modifs sont persistantes ?

03/04/2019 à 16:26
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Absolument pas. Si tu as des accès concurrents, utilise un sync.RWMutex ou un sync.Map.

03/04/2019 à 10:32
guyot-jerome
Membre Actif
Avatar de guyot-jerome
guyot-jerome
Membre Actif

C'est thread-safe les maps en Go ?

03/04/2019 à 03:06
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Go ne permet pas de trier une map nativement. Tu dois extraire les clés dans un slice, trier le slice, puis itérer.

keys := make([]string, 0, len(notes))
for k := range notes { keys = append(keys, k) }
sort.Strings(keys)
02/04/2019 à 20:11
barre-gilles
Membre Actif
Avatar de barre-gilles
barre-gilles
Membre Actif

J'ai besoin de trier ma map par clé, vous faites comment ?

02/04/2019 à 14:14
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Exact, c'est une opération no-op. Ça ne panique pas, c'est safe.

02/04/2019 à 07:20
baron-alexandre
Membre Rédacteur
Avatar de baron-alexandre
baron-alexandre
Membre Rédacteur

Le delete() ne fait rien si la clé n'existe pas ?

01/04/2019 à 23:54
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Tu peux ignorer la valeur avec _ :

for k := range notes {
    fmt.Println("Clé :", k)
}
01/04/2019 à 17:45
guy31
Membre Actif
Avatar de guy31
guy31
Membre Actif

Quelqu'un peut me donner un exemple de range propre pour récupérer juste les clés ?

01/04/2019 à 11:44
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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 à nil pour que le GC fasse le taff.

01/04/2019 à 06:12
thomas-breton
Membre Actif
Avatar de thomas-breton
thomas-breton
Membre Actif

J'ai une map énorme et je veux libérer la mémoire. delete() suffit ou il faut faire autre chose ?

31/03/2019 à 22:54
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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.

31/03/2019 à 18:12
josephine16
Membre Actif
Avatar de josephine16
josephine16
Membre Actif

La boucle for range est bien pratique mais l'ordre d'itération me semble aléatoire. C'est un bug ?

31/03/2019 à 11:27
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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.

31/03/2019 à 07:10
cecile37
Membre Actif
Avatar de cecile37
cecile37
Membre Actif

J'ai testé avec un slice en clé et le compilateur m'a envoyé bouler. Pourquoi ?

30/03/2019 à 23:44
lacroix-louis
Membre Actif
Avatar de lacroix-louis
lacroix-louis
Membre Actif

Est-ce qu'on peut utiliser une struct comme clé ?

30/03/2019 à 18:03
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Utilise l'idiome val, ok := notes[key]. Si ok est false, la clé n'existe pas.

30/03/2019 à 10:03
vincent-bertrand
Membre Actif
Avatar de vincent-bertrand
vincent-bertrand
Membre Actif

Comment on fait pour vérifier si une clé existe vraiment dans la map sans récupérer une valeur par défaut ?

30/03/2019 à 02:46
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

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.

29/03/2019 à 20:29
morin-paul
Membre Actif
Avatar de morin-paul
morin-paul
Membre Actif

J'essaie de déclarer ma map avec var notes map[string]int mais quand je fais un notes["test"] = 10, ça me balance un panic runtime. C'est normal ?

29/03/2019 à 15:45

Rejoindre la communauté

Recevoir les derniers articles gratuitement en créant un compte !

S'inscrire