Retour au cours

backend / go

Structures de contrôle

Leçon 31 exercice

Explication

Ce que vous allez apprendre

  • Écrire des conditions if/else if/else sans parenthèses mais avec des accolades obligatoires
  • Utiliser la seule boucle de Go, for, sous ses quatre formes (classique, while, infinie, range)
  • Comprendre pourquoi switch en 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.

FormeSyntaxeÉquivalent dans d'autres langages
Classiquefor i := 0; i < 5; i++ { }for en C/Java
Type "while"for condition { }while
Infiniefor { }while (true)
Sur collectionfor 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.

go
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 en for i:=..., while, infinie, range.
  • switch ne tombe pas au cas suivant par défaut (pas de break requis).
  • Les labels (Boucle:) permettent continue/break sur une boucle externe.

Exercices pratiques

1 disponible
1

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.

Résoudre l’exercice →