backend / go
Structures de contrôle
Explication
Ce que vous allez apprendre
- Écrire des conditions
if/else if/elsesans parenthèses mais avec des accolades obligatoires - Utiliser la seule boucle de Go,
for, sous ses quatre formes (classique, while, infinie, range) - Comprendre pourquoi
switchen Go ne "tombe" pas au cas suivant par défaut - Parcourir un slice ou une map avec
for ... range - Utiliser des labels pour contrôler des boucles imbriquées avec
continue/break
Dans quel contexte ?
Un développeur qui vient de Java ou C attaque son premier switch en Go et s'attend, par réflexe, à devoir écrire un break à la fin de chaque case pour éviter que l'exécution ne continue dans le cas suivant. En Go, ce réflexe est non seulement inutile mais souvent signe d'une incompréhension du langage : cette leçon désamorce ce piège avant qu'il ne devienne une habitude.
D'abord, la simplicité volontaire des conditions
Go retire les parenthèses autour de la condition d'un if, contrairement à C ou Java (if age < 18 et non if (age < 18)). En revanche, les accolades ne sont jamais optionnelles, même pour un bloc d'une seule ligne — un choix qui élimine une classe de bugs historiques liés à l'indentation trompeuse.
Un if peut aussi contenir une instruction d'initialisation avant sa condition, comme if score := calculer(); score >= 60 { ... }. La variable score n'existe alors que dans la portée de ce if (et de son else éventuel), ce qui évite de polluer le reste de la fonction avec des variables temporaires.
Une fois les conditions comprises, il faut assimiler l'unique boucle de Go
Contrairement à la plupart des langages qui proposent for, while et do-while séparément, Go n'a qu'un seul mot-clé : for. Sa syntaxe change selon ce qu'on lui fournit.
| Forme | Syntaxe | Équivalent dans d'autres langages |
|---|---|---|
| Classique | for i := 0; i < 5; i++ { } | for en C/Java |
| Type "while" | for condition { } | while |
| Infinie | for { } | while (true) |
| Sur collection | for i, v := range slice { } | for...of / foreach |
Cette unification simplifie l'apprentissage : une fois for maîtrisé sous ses quatre formes, il n'y a plus rien d'autre à apprendre côté boucles.
Prérequis
Il faut être à l'aise avec les variables et les types de base (leçon précédente) pour comprendre les exemples de cette leçon, notamment les slices utilisés dans les boucles range.
Ensuite, le comportement qui déroute le plus les débutants venus d'ailleurs
En C, C++ ou Java, un switch continue d'exécuter les cas suivants après une correspondance, sauf break explicite (le "fallthrough" implicite). Go inverse cette logique par défaut : chaque case s'arrête automatiquement après son exécution.
Piège fréquent
Ajouter un break à la fin de chaque case en Go, par réflexe venu d'un autre langage, ne casse rien mais révèle une incompréhension du modèle — et dans le pire cas, utiliser volontairement fallthrough sans en comprendre l'effet peut faire exécuter un cas qu'on ne voulait pas déclencher. Retiens la règle inverse de C : en Go, il faut ajouter fallthrough explicitement pour obtenir l'ancien comportement, jamais l'inverse.
Un switch sans expression (switch { case cond1: ... }) est une alternative très lisible à une longue chaîne de if/else if, particulièrement utile pour des tranches de valeurs comme des notes ou des tarifs.
Bonne pratique
Utilise for _, v := range slice quand seul l'élément t'intéresse (pas l'index), c'est l'idiome le plus lisible et il évite une variable inutile qui traînerait dans le code.
Maintenant que ton programme sait décider et répéter, il te manque la brique suivante pour structurer une vraie logique : découper ton code en fonctions réutilisables, avec la gestion d'erreurs idiomatique de Go — c'est le sujet de la prochaine leçon.
Commandes & code
Structures de contrôle
Go n'a qu'une seule boucle (for), pas de parenthèses obligatoires, des accolades obligatoires.
package main
import "fmt"
func main() {
age := 17
// if / else if / else
if age < 13 {
fmt.Println("enfant")
} else if age < 18 {
fmt.Println("adolescent")
} else {
fmt.Println("adulte")
}
// if avec instruction d'initialisation (portee limitee au bloc)
if score := 85; score >= 60 {
fmt.Println("admis avec", score)
}
// for classique
for i := 0; i < 5; i++ {
fmt.Print(i, " ")
}
fmt.Println()
// for comme "while"
compteur := 0
for compteur < 3 {
compteur++
}
// for infini + break
total := 0
for {
total++
if total >= 10 {
break
}
}
// for-range sur slice, string, map
fruits := []string{"pomme", "banane", "cerise"}
for index, fruit := range fruits {
fmt.Println(index, fruit)
}
for _, fruit := range fruits { // "_" ignore l'index
fmt.Println(fruit)
}
// switch : pas de fallthrough par defaut (contrairement a C/Java)
jour := 3
switch jour {
case 1, 7:
fmt.Println("week-end")
case 2, 3, 4, 5, 6:
fmt.Println("jour ouvre")
default:
fmt.Println("jour invalide")
}
// switch sans expression = alternative lisible a de longs if/else if
note := 72
switch {
case note >= 90:
fmt.Println("A")
case note >= 75:
fmt.Println("B")
default:
fmt.Println("C")
}
// continue et labels pour sortir de boucles imbriquees
Boucle:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if j == 1 {
continue Boucle
}
fmt.Println(i, j)
}
}
}Résumé
- Une seule boucle
for, déclinée enfor i:=...,while, infinie,range. switchne tombe pas au cas suivant par défaut (pas debreakrequis).- Les labels (
Boucle:) permettentcontinue/breaksur une boucle externe.
Exercices pratiques
Mission : un switch porté depuis Java qui exécute deux cas d'un coup
Objectif : Corriger un switch mal transposé depuis Java, puis maîtriser les labels pour contrôler des boucles imbriquées.
Contexte
Un développeur qui vient de Java a porté une fonction de classification de commandes vers Go. Son switch sur le statut de la commande exécute parfois DEUX blocs de traitement à la suite pour un seul statut, ce qui double des envois d'email de notification en production.