Le if de Go n'a pas de parenthèses autour de la condition, exige toujours des accolades, et peut commencer par une courte instruction qui déclare des variables dont la portée se limite au if.
Les conditions sont testées de haut en bas et la première branche vraie s'exécute. else if et else sont facultatifs.
Règles de syntaxe
Trois règles diffèrent de C, Java et JavaScript :
- Pas de parenthèses autour de la condition.
if (x > 5)compile, maisgofmtretire les parenthèses. - Les accolades sont obligatoires, même pour une seule instruction. Il n'existe pas de
if x > 5 returnsans accolades. elsese place sur la même ligne que l'accolade fermante. Go insère un point-virgule après une}en fin de ligne, donc ceci échoue :
if x > 5 {
fmt.Println("big")
}
else {
fmt.Println("small")
}
syntax error: unexpected keyword else, expected }
Écrivez } else { sur une seule ligne.
La condition doit être un bool. Go ne traite pas 0, "" ou nil comme faux, donc if count {} et if name {} ne compilent pas. Comparez explicitement : if count > 0, if name != "", if user != nil.
Combinez les conditions avec && (et), || (ou) et ! (non). && et || s'évaluent en court-circuit, ce qui rend les tests de nil sûrs :
if user != nil && user.IsAdmin() {
// user.IsAdmin() is only called when user is not nil
}
if avec une instruction d'initialisation
Un if peut exécuter une courte instruction avant la condition, séparée par un point-virgule. Les variables qui y sont déclarées sont visibles dans toutes les branches de ce if, et nulle part après :
Ce motif garde les variables à courte durée de vie hors de la portée environnante. On le voit sans cesse avec les recherches dans une map (v, ok := m[k]), les assertions de type (s, ok := v.(string)) et les erreurs.
Le revers : si vous avez besoin de la valeur après le if, déclarez-la plutôt avant. Une erreur fréquente consiste à placer un résultat dans l'instruction d'initialisation puis à essayer de l'utiliser plus bas.
L'idiome if err != nil
Les fonctions qui peuvent échouer renvoient une error en dernier. Vérifiez-la immédiatement, traitez-la ou renvoyez-la, et continuez le chemin nominal sans indentation :
Remarquez qu'il n'y a pas de else après if err != nil { return ... }. Le style Go traite l'erreur, retourne, et laisse le flux normal contre la marge gauche. La page sur la gestion des erreurs couvre l'enveloppement et la vérification des types d'erreur.
Retours anticipés plutôt qu'imbrication
Des blocs if profondément imbriqués sont difficiles à lire. Inversez les conditions et retournez tôt ; chaque vérification se lit alors comme une garde :
// Nested
func canCheckout(u *User, cart *Cart) bool {
if u != nil {
if u.Verified {
if len(cart.Items) > 0 {
return true
}
}
}
return false
}
// Guards
func canCheckout(u *User, cart *Cart) bool {
if u == nil || !u.Verified {
return false
}
if len(cart.Items) == 0 {
return false
}
return true
}
Les développeurs Go appellent cela garder le chemin nominal aligné à gauche. Des linters comme revive signalent un else après un bloc qui se termine par return, parce que ce else ajoute de l'indentation pour rien.
if/else ou switch
Une longue chaîne de else if qui teste une valeur contre plusieurs cas se lit mieux sous forme de switch. Un switch sans expression remplace une chaîne if/else if de conditions quelconques :
switch {
case score >= 90:
return "A"
case score >= 80:
return "B"
default:
return "F"
}
Utilisez if pour une ou deux branches, et switch à partir de trois.
Pas d'opérateur ternaire
Go n'a pas de cond ? a : b. Affectez avec un if :
label := "odd"
if n%2 == 0 {
label = "even"
}
La page sur l'opérateur ternaire explique pourquoi et montre les alternatives.
Erreurs courantes
- Le masquage avec :=.
if x, err := f(); err == nil { ... }déclare un nouveauxuniquement pour leif. Unxextérieur n'est pas mis à jour. - Une affectation dans la condition.
if x = 5 {}est une erreur de compilation (cannot use assignment x = 5 as value), pas un bug silencieux comme en C. Utilisez==. - Comparer des flottants avec ==.
if total == 0.3échoue pour des valeurs calculées. Comparez avec une tolérance. - Vérifier la mauvaise erreur. Après
a, err := f()etb, err := g(), assurez-vous que chaqueif err != nilsuit directement son appel.
Questions fréquentes
Comment écrire if else en Go ?
Sans parenthèses autour de la condition, et avec des accolades toujours obligatoires :
if x > 10 {
fmt.Println("big")
} else if x > 5 {
fmt.Println("medium")
} else {
fmt.Println("small")
}
else doit être sur la même ligne que l'accolade fermante du bloc précédent.
Qu'est-ce qu'un if avec instruction d'initialisation en Go ?
Une courte instruction avant la condition, séparée par un point-virgule : if n, err := strconv.Atoi(s); err != nil { ... }. Les variables qui y sont déclarées n'existent qu'à l'intérieur du if et de ses branches else if et else, ce qui les empêche de déborder dans le reste de la fonction.
Peut-on écrire un if sur une ligne en Go ?
Pas sans accolades. if ok return et if (ok) x = 1; sont des erreurs de syntaxe. La forme la plus courte est if ok { return }, et gofmt place le corps sur sa propre ligne. Go n'a pas non plus d'opérateur ternaire, donc une valeur conditionnelle demande un if/else ou une petite fonction utilitaire.
Pourquoi Go utilise-t-il if err != nil partout ?
Go n'a pas d'exceptions. Les fonctions qui peuvent échouer renvoient une error comme dernier résultat, et l'appelant la vérifie tout de suite avec if err != nil. La répétition est le prix à payer pour que chaque point d'échec soit visible là où il se produit.