Code review en Go : que vérifier et comment donner un retour
Code review (révision de code) n'est pas qu'une simple formalité, mais l'un des outils les plus efficaces pour améliorer la qualité du code, partager les connaissances au sein de l'équipe et prévenir les bugs. Dans la communauté Go (Golang), le code review a une importance particulière, car le langage encourage la simplicité, la lisibilité et l'idiomaticité. Dans cet article, nous allons voir sur quoi se concentrer lors de la révision de code Go et comment donner un feedback utile, sans être blessant.
1. Principes généraux du code review en Go
Avant d'entrer dans les détails techniques, il est important de se rappeler la culture de la révision. Votre objectif est d'améliorer le code et d'aider un collègue, pas de prouver que vous avez raison. Voici quelques règles d'or :
- Soyez constructif. Au lieu de « c'est mauvais », écrivez « il pourrait y avoir une fuite de goroutine ici, ajoutons un contexte ».
- Demandez, n'affirmez pas. « Pourquoi as-tu choisi
sync.Mutexplutôt qu'un canal ? » est une bonne question. « T'es idiot, il fallait un canal » est une mauvaise. - Ne retardez pas la révision. Efforcez-vous de répondre dans les 24 heures (ou selon l'accord dans l'équipe).
- Concentrez-vous sur la logique et l'architecture. Les corrections stylistiques (espaces, indentations) sont mieux laissées à
gofmt.
2. Que vérifier en priorité : checklist pour Go
Voici une liste structurée de ce sur quoi il faut se concentrer lors de la révision de code Go. Divisons-la en blocs logiques.
2.1. Gestion des erreurs
En Go, il n'y a pas d'exceptions, les erreurs sont des valeurs. C'est l'une des idiomes clés du langage.
- Vérifiez toutes les erreurs retournées. Ignorer une erreur avec
_n'est acceptable que dans de très rares cas (par exemple, lors de l'écriture dansio.Discard). - N'utilisez pas
panicpour les erreurs courantes.panicest réservé aux états irrécupérables (par exemple, une erreur d'initialisation du serveur). - Enveloppez les erreurs. Utilisez
fmt.Errorf("quelque chose s'est mal passé : %w", err)pour ajouter du contexte. Cela permet d'utilisererrors.Is()eterrors.As().
// Mauvais : perte de contexteif err != nil { return err}
// Bon : on enveloppe l'erreurif err != nil { return fmt.Errorf("impossible d'ouvrir le fichier %s : %w", filename, err)}2.2. Goroutines et concurrence
Go est célèbre pour sa concurrence légère, mais c'est aussi une source de nombreux bugs.
- Fuites de goroutines. Assurez-vous que chaque goroutine lancée se termine un jour. Utilisez le contexte (
context.Context) pour l'annulation. - Utilisation correcte des canaux. Celui qui crée le canal le ferme. La fermeture du canal est la responsabilité de l'expéditeur.
- Data race (condition de concurrence). Évitez d'écrire simultanément dans une même variable sans synchronisation. Utilisez des mutex (
sync.Mutex) ou des atomiques (sync/atomic).
// Exemple avec contexte pour annuler une goroutinefunc process(ctx context.Context, dataCh chan int) { for { select { case <-ctx.Done(): log.Println("Arrêt du travail") return case val, ok := <-dataCh: if !ok { return // canal fermé } fmt.Println(val) } }}2.3. Idiomes et style Go
Go est un langage où la lisibilité du code est primordiale.
- Noms de variables. Des noms courts pour des portées courtes.
ipour une boucle,rpour un reader. Pour les variables globales, des noms plus longs. - Évitez les « nombres magiques ». Utilisez des constantes.