En Go, les variables déclarées sans initialiseur explicite obtiennent automatiquement ce qu'on appelle des valeurs nulles (zero values), qui diffèrent selon les types :
int — 0bool — falsestring — ""C'est pratique (absence de déchets en mémoire), mais cela peut être dangereux : pour certains types, comme les slices et les maps, travailler avec une valeur nil peut entraîner un panic ou des bugs.
Exemple :
var m map[string]int m["key"] = 1 // panic : affectation à une entrée dans une map nil var s []int fmt.Println(s, s == nil) // [] true (on peut ajouter des éléments, mais pas accéder par index)
Quelle est la différence entre une valeur nil d'un slice et une valeur nil d'une map/canal, et quels bugs cela entraîne-t-il ?
La réponse correcte : Un slice avec une valeur nil peut être passé à des fonctions, utilisé avec append et range — c'est sûr, mais travailler avec une map nil entraînera un panic en cas de tentative d'écriture (mais la lecture est autorisée et renverra une valeur nulle).
Exemple:
var m map[string]int fmt.Println(m["no_key"]) // 0 — c'est sûr m["key"] = 1 // panic! var s []int s = append(s, 42) // ok
Histoire
Description : Dans un grand projet, des maps non initialisées étaient utilisées pour l'agrégation de données. Lors de la première écriture, l'application chutait systématiquement avec un panic. Le problème a été découvert en production, lorsque de nouvelles statistiques ont été introduites.
Histoire
Description : Un service a sérialisé un slice non initialisé, l'envoyant en tant que JSON dans la réponse API. Au lieu de
[], les clients recevaientnull— il a fallu changer le schéma côté frontal pour gérer les deux variantes.
Histoire
Description : Dans un module de mise en cache, une comparaison incorrecte entre une map nil et une map vide amenait à une détermination incorrecte de la présence d'éléments. Cela entraînait des requêtes inutiles à la base de données, diminuant les performances.