if / else : sans parenthèses, avec accolades
En Go, le if ressemble à ce que vous connaissez, avec deux différences qui surprennent au début : pas de parenthèses autour de la condition, et les accolades sont obligatoires, même pour une seule ligne.
age := 20
if age >= 18 {
fmt.Println("Majeur")
} else {
fmt.Println("Mineur")
}
// Avec else if
note := 14
if note >= 16 {
fmt.Println("Très bien")
} else if note >= 12 {
fmt.Println("Bien")
} else {
fmt.Println("Peut mieux faire")
}
L'accolade ouvrante doit être sur la même ligne que le if : c'est une règle du compilateur, pas un choix de style. Le formateur gofmt impose tout le reste, donc plus de débats sur l'indentation dans les revues de code.
Sortie attendue :
Majeur
Bien
if avec instruction d'initialisation
Go permet de déclarer une variable juste avant la condition, dans le if lui-même. La variable n'existe alors que dans le bloc if (et son else). C'est la forme la plus idiomatique de Go, celle que vous croiserez partout pour gérer les erreurs :
if err := faireQuelqueChose(); err != nil {
fmt.Println("Échec :", err)
return
}
// err n'existe plus ici : sa portée était limitée au if
Bonne pratique : la forme if err := f(); err != nil { } est le réflexe numéro un en Go. Elle garde la variable err confinée au bloc où elle sert, sans polluer le reste de la fonction. Vous la verrez dans presque chaque programme Go.
Le même principe marche pour n'importe quel calcul, pas seulement les erreurs :
if reste := nombre % 2; reste == 0 {
fmt.Println("Pair")
} else {
fmt.Println("Impair")
}
for : la seule boucle de Go
Go n'a qu'un seul mot-clé de boucle : for. Pas de while, pas de do...while. Mais for prend plusieurs formes qui couvrent tous les besoins.
1. La forme classique (init ; condition ; incrément), comme en C ou Java :
for i := 0; i < 3; i++ {
fmt.Println(i) // 0, 1, 2
}
2. La forme « while » : juste une condition, et c'est tout :
n := 1
for n < 10 {
n *= 2 // 1, 2, 4, 8
}
3. La boucle infinie : aucune condition, on en sort avec break :
compteur := 0
for {
compteur++
if compteur == 3 {
break // on quitte la boucle
}
}
4. La forme range : parcourt une slice (ou une map, une chaîne...) en donnant l'index et la valeur :
fruits := []string{"pomme", "poire", "kiwi"}
for i, v := range fruits {
fmt.Println(i, v) // 0 pomme, 1 poire, 2 kiwi
}
Si l'index ne vous intéresse pas, remplacez-le par _ (le trou noir de Go) : for _, v := range fruits.
À vous d'essayer :
package main
import "fmt"
func main() {
// Forme classique
for i := 0; i < 3; i++ {
fmt.Println("classique :", i)
}
// Forme while
n := 1
for n < 10 {
n *= 2
}
fmt.Println("while final :", n)
// Forme range
fruits := []string{"pomme", "poire", "kiwi"}
for i, v := range fruits {
fmt.Println("range :", i, v)
}
}
switch : sans break, sans fallthrough
Le switch de Go corrige le piège le plus connu du C : pas besoin d'écrire break. Chaque case s'arrête tout seul. Pas de fallthrough accidentel qui exécute le case suivant par erreur.
jour := "samedi"
switch jour {
case "samedi":
fmt.Println("Week-end !")
case "dimanche":
fmt.Println("Week-end !")
default:
fmt.Println("Au travail")
}
Vous pouvez regrouper plusieurs valeurs sur un même case, séparées par des virgules :
switch jour {
case "samedi", "dimanche":
fmt.Println("Week-end !")
default:
fmt.Println("Au travail")
}
Et le plus élégant : un switch sans condition, qui remplace avantageusement une cascade de if / else if :
note := 14
switch {
case note >= 16:
fmt.Println("Très bien")
case note >= 12:
fmt.Println("Bien")
default:
fmt.Println("Peut mieux faire")
}
Attention : si vous voulez vraiment enchaîner sur le case suivant (le comportement par défaut du C), il faut l'écrire explicitement avec le mot-clé fallthrough. Sans lui, chaque case est isolé. C'est l'inverse du C, ne vous faites pas avoir.
À vous d'essayer :
package main
import "fmt"
func main() {
note := 14
switch {
case note >= 16:
fmt.Println("Très bien")
case note >= 12:
fmt.Println("Bien")
default:
fmt.Println("Peut mieux faire")
}
jour := "dimanche"
switch jour {
case "samedi", "dimanche":
fmt.Println("Week-end !")
default:
fmt.Println("Au travail")
}
}
Récap
Trois structures de contrôle, et c'est tout ce dont Go a besoin :
ifsans parenthèses, accolades obligatoires, avec l'instruction d'initif x := f(); x != nilen réflexe quotidien.for: l'unique boucle, sous quatre formes (classique, while, infinie +break, etrange).switch: pas debreak, cases multiples avec virgules, et la version sans condition qui remplace les cascades deif / else if.
if / else: no parentheses, braces required
In Go, if looks like what you already know, with two differences that surprise newcomers: no parentheses around the condition, and braces are mandatory, even for a single line.
age := 20
if age >= 18 {
fmt.Println("Adult")
} else {
fmt.Println("Minor")
}
// With else if
score := 14
if score >= 16 {
fmt.Println("Excellent")
} else if score >= 12 {
fmt.Println("Good")
} else {
fmt.Println("Needs work")
}
The opening brace must be on the same line as the if: this is a compiler rule, not a style choice. The gofmt formatter enforces everything else, so no more indentation debates in code reviews.
Expected output:
Adult
Good
if with an init statement
Go lets you declare a variable right before the condition, inside the if itself. That variable then only exists within the if block (and its else). This is Go's most idiomatic form, the one you'll meet everywhere for handling errors:
if err := doSomething(); err != nil {
fmt.Println("Failed:", err)
return
}
// err no longer exists here: its scope was limited to the if
Best practice: the if err := f(); err != nil { } form is the number-one reflex in Go. It keeps the err variable confined to the block where it's used, without polluting the rest of the function. You'll see it in almost every Go program.
The same principle works for any computation, not just errors:
if rem := number % 2; rem == 0 {
fmt.Println("Even")
} else {
fmt.Println("Odd")
}
for: Go's only loop
Go has a single loop keyword: for. No while, no do...while. But for takes several forms that cover every need.
1. The classic form (init; condition; increment), just like in C or Java:
for i := 0; i < 3; i++ {
fmt.Println(i) // 0, 1, 2
}
2. The "while" form: just a condition, nothing else:
n := 1
for n < 10 {
n *= 2 // 1, 2, 4, 8
}
3. The infinite loop: no condition, you exit it with break:
counter := 0
for {
counter++
if counter == 3 {
break // we leave the loop
}
}
4. The range form: iterates over a slice (or a map, a string...) giving the index and the value:
fruits := []string{"apple", "pear", "kiwi"}
for i, v := range fruits {
fmt.Println(i, v) // 0 apple, 1 pear, 2 kiwi
}
If you don't care about the index, replace it with _ (Go's black hole): for _, v := range fruits.
switch: no break, no fallthrough
Go's switch fixes the most famous C pitfall: no need to write break. Each case stops on its own. No accidental fallthrough running the next case by mistake.
day := "saturday"
switch day {
case "saturday":
fmt.Println("Weekend!")
case "sunday":
fmt.Println("Weekend!")
default:
fmt.Println("Back to work")
}
You can group several values on a single case, separated by commas:
switch day {
case "saturday", "sunday":
fmt.Println("Weekend!")
default:
fmt.Println("Back to work")
}
And the most elegant: a switch without a condition, which neatly replaces a cascade of if / else if:
score := 14
switch {
case score >= 16:
fmt.Println("Excellent")
case score >= 12:
fmt.Println("Good")
default:
fmt.Println("Needs work")
}
Warning: if you really want to chain onto the next case (the default C behavior), you must write it explicitly with the fallthrough keyword. Without it, each case is isolated. This is the opposite of C, don't get caught out.
Recap
Three control structures, and that's all Go needs:
ifwith no parentheses, mandatory braces, and the init statementif x := f(); x != nilas a daily reflex.for: the only loop, in four forms (classic, while, infinite +break, andrange).switch: nobreak, multiple cases with commas, and the condition-less version that replacesif / else ifcascades.
Copiez les boucles et les switch ci-dessus et testez-les dans le Go Playground :
Copiez ce prompt dans Claude ou ChatGPT :
Écris un programme Go qui parcourt les nombres de 1 à 20 avec une boucle for, et affiche "Fizz" pour les multiples de 3, "Buzz" pour les multiples de 5, "FizzBuzz" pour les deux. Utilise un switch sans condition.
Sans relire la leçon : en quoi le switch de Go diffère de celui du C, et que fait le mot-clé fallthrough ?
case s'arrête tout seul, pas besoin d'écrire break et donc aucun fallthrough accidentel comme en C. fallthrough est le mot-clé explicite à ajouter quand on veut volontairement enchaîner sur le case suivant. Bonus : un switch sans condition remplace une cascade de if / else if.L'IA te propose cette boucle de catégorisation. Ton rôle de relecteur : l'accepter telle quelle ou la rejeter, et dire pourquoi.
for _, note := range notes {
switch {
case note >= 16:
fmt.Println("Très bien")
case note >= 12:
fmt.Println("Bien")
fallthrough
default:
fmt.Println("Peut mieux faire")
}
}
fallthrough après le case note >= 12 n'a rien à faire là : une note de 14 affichera "Bien" PUIS "Peut mieux faire", deux verdicts contradictoires. C'est exactement le piège que le switch de Go évite par défaut, et que ce fallthrough réintroduit. Sans lui le code est correct. Demande à l'IA pourquoi ce fallthrough est là : neuf fois sur dix c'est une scorie inutile.Sans remonter dans la leçon : combien de mots-clés de boucle a Go, et comment écrire une boucle « tant que » (while) avec ?
for (ni while ni do...while). Pour une boucle « tant que », on écrit un for avec une condition seule : for n < 10 { n *= 2 }. La même boucle couvre aussi la forme classique for i := 0; i < 3; i++, la boucle infinie for { } avec break, et la forme for i, v := range fruits.if err := f(); err != nil { } ?You've mastered conditions and Go's single loop. Now we'll fill those loops with real data structures: slices (dynamic arrays) and maps (key-value pairs), the two collections you'll handle every day.
Lesson 4: Slices and maps →