Chasse aux clés : comment ne pas se perdre dans les méandres des maps Go
\nImaginez : vous écrivez un microservice en Go. Vous devez vérifier rapidement si un utilisateur est enregistré dans le système. Vous consultez une map, où la clé est l'ID de l'utilisateur et la valeur son profil. Et là, la question se pose : cette clé existe-t-elle vraiment dans la map ?
\nSi vous venez de Python ou JavaScript, vous avez l'habitude qu'accéder à une clé inexistante puisse lever une exception ou renvoyer undefined. En Go, c'est différent. Il n'y a pas d'exceptions, mais il existe un mécanisme élégant. Et si vous essayez de lire une valeur avec une clé qui n'existe pas, Go ne plantera pas, il renverra simplement la valeur zéro pour le type de la valeur.
C'est pratique ? Oui, mais c'est aussi un piège. Comment distinguer la situation « la clé n'existe pas » de la situation « la clé existe, mais sa valeur est zéro » ? C'est exactement pour cela qu'il existe un idiome spécial : l'idiome comma ok. Décortiquons-le une fois pour toutes.
\n\nComment fonctionne une map en Go : petit rappel
\nAvant de plonger dans les vérifications, rappelons ce qu'est une map en Go. C'est une table de hachage qui stocke des paires clé-valeur. Syntaxe de déclaration :
\n// Déclaration d'une map : clés de type string, valeurs de type int\nvar scores map[string]int\n\n// Initialisation d'une map vide (obligatoire !)\nscores = make(map[string]int)\n\n// Ou directement avec des données\nscores := map[string]int{\n "Alice": 95,\n "Bob": 87,\n}\nPoint important : si vous essayez d'écrire une valeur dans une map non initialisée (nil map), le programme plantera avec une panique. Ne faites jamais cela !
\n\nLa méthode principale : l'affectation à deux valeurs (idiome comma ok)
\nC'est la manière la plus correcte et idiomatique de vérifier si une clé existe dans une map en Go.
\nLa syntaxe est la suivante :
\nvalue, ok := myMap[key]\nIci :
\n- \n
value— la valeur correspondant à la clé (ou la valeur zéro si la clé n'existe pas) \n ok— une variable booléenne qui vauttruesi la clé existe, etfalsesinon \n
Regardons un exemple complet :
\npackage main\n\nimport "fmt"\n\nfunc main() {\n // Création d'une map avec les notes des étudiants\n grades := map[string]int{\n "Marie": 88,\n "Pierre": 92,\n "Anne": 0, // Oui, Anne a 0 points\n }\n\n // Vérification de la clé "Pierre"\n if grade, ok := grades["Pierre"]; ok {\n fmt.Printf("Note de Pierre : %d\\n", grade)\n } else {\n fmt.Println("Pierre n'est pas dans la liste")\n }\n\n // Vérification de la clé "Jean"\n if grade, ok := grades["Jean"]; ok {\n fmt.Printf("Note de Jean : %d\\n", grade)\n } else {\n fmt.Println("Jean n'est pas dans la liste")\n }\n\n // Cas complexe : la clé "Anne" existe, mais la valeur est 0\n if grade, ok := grades["Anne"]; ok {\n fmt.Printf("Note d'Anne : %d\\n", grade) // Affichera : Note d'Anne : 0\n }\n}\nRemarquez : pour la clé « Anne », ok sera true, même si la valeur est zéro. C'est pourquoi il ne faut pas se fier uniquement à la vérification de la valeur !
Pourquoi ne peut-on pas simplement comparer avec la valeur zéro ?
\nBeaucoup de débutants commettent cette erreur. Ils écrivent quelque chose comme :
\nif grades["Jean"] != 0 {\n fmt.Println("Jean est dans la liste !")\n}\nC'est incorrect pour deux raisons :
\n- \n
- Pour les types numériques : si Jean a réellement une note de 0, vous le manquerez. \n
- Pour les autres types : la valeur zéro peut être une chaîne vide (
""),falseounil. Vous ne pourrez pas distinguer « pas de clé » de « clé existe, mais valeur vide ». \n
La seule méthode fiable est d'utiliser l'idiome comma ok.
\n\nVérification de clé sans récupérer la valeur
\nParfois, vous avez simplement besoin de savoir si une clé existe, sans la valeur elle-même