Introduction : Pourquoi Go semble simple mais cache des pièges
Go (Golang) est un langage compilé et typé statiquement créé chez Google. Il est souvent loué pour sa syntaxe simple, son support intégré de la concurrence et ses performances élevées. Cependant, cette apparente simplicité joue souvent un tour cruel aux débutants venant de langages dynamiques (Python, JavaScript) ou même du C++.
De nombreux développeurs, lorsqu'ils commencent à écrire en Go, commettent les mêmes erreurs typiques. Dans cet article, nous allons décomposer les 5 problèmes les plus courants auxquels les développeurs Go débutants sont confrontés et montrer comment les corriger avec des exemples de code clairs.
1. Ignorer les erreurs retournées (Gestion des erreurs)
Le problème
Go n'a pas d'exceptions (try-catch). Une erreur est simplement une valeur qu'une fonction retourne comme dernier argument. L'erreur la plus courante des débutants est d'assigner le résultat à une variable mais d'ignorer l'erreur en utilisant le trait de soulignement _.
// MAUVAIS : l'erreur est avaléerésultat, _ := faireQuelqueChose()fmt.Println(résultat)Pourquoi est-ce mauvais ?
Le programme continuera de fonctionner avec des données incorrectes, ce qui peut entraîner des paniques, des fuites mémoire ou des bugs logiques difficiles à détecter.
Comment faire correctement
Vérifiez toujours l'erreur. Utilisez le modèle idiomatique :
// BON : l'erreur est géréerésultat, err := faireQuelqueChose()if err != nil { log.Printf("Erreur lors de l'exécution de faireQuelqueChose : %v", err) return // ou panic, ou autre logique}fmt.Println(résultat)Conseil : Écrivez votre code de sorte que if err != nil devienne un réflexe. N'ayez pas peur des retours précoces — cela rend le code plus propre.
2. Confusion entre nil et les Slices/Maps vides
Le problème
En Go, nil n'est pas un "objet vide". C'est la valeur zéro pour les pointeurs, slices, maps, canaux et interfaces. Les débutants essaient souvent d'écrire des données dans une map ou un slice nil, ce qui provoque une panique.
// MAUVAIS : panique lors de l'écriture dans une map nilvar m map[string]intm["clé"] = 42 // panique : assignment to entry in nil mapComment faire correctement
Initialisez toujours les maps et les slices avant utilisation :
// BON : initialisation via makem := make(map[string]int)m["clé"] = 42
// Ou via un littéralm2 := map[string]int{}m2["clé"] = 42La situation avec les slices est plus délicate : vous pouvez lire un slice nil (il retourne un slice vide), mais vous ne pouvez pas y écrire par index. Utilisez append :
var s []ints = append(s, 1) // OK, crée un nouveau slice// s[0] = 1 // panique : runtime error: index out of range [0] with length 03. Utilisation incorrecte des Goroutines et courses de données
Le problème
Les goroutines sont des threads légers. Les débutants lancent souvent des goroutines en oubliant de synchroniser l'accès aux données partagées. Cela conduit à une course de données — un comportement de programme indéfini.
// MAUVAIS : course de donnéesvar compteur intfor i := 0; i < 1000; i++ { go func() { compteur++ // dangereux ! }()}time.Sleep(time.Second)fmt.Println(compteur) // résultat imprévisibleComment faire correctement
Utilisez des mutex (sync.Mutex) ou des canaux pour la synchronisation :
// BON : utilisation d'un mutexvar ( compteur int mu sync.Mutex)for i := 0; i < 1000; i++ { go func() { mu.Lock() compteur++ mu.Unlock() }()}// Attendre la fin (mieux vaut utiliser sync.WaitGroup)time.Sleep(time.Second)fmt.Println(compteur) // 1000Important : Vérifiez toujours votre code pour les courses avec le flag -race : go run -race main.go.