Les boucles dans le langage de programmation Go

Ce chapitre vous explique les boucles en GoLang. Les boucles permettent d'itérer un bloc de code plusieurs fois. On apprendra à utiliser la boucle for avec les mots-clés break et continue dans le langage de programmation Go.

Description

Une boucle est un moyen d'exécuter un bloc de code plusieurs fois, suivant le résultat d’une condition ou selon un nombre d'itérations connu à l'avance.

Information

Une itération correspond à un tour de boucle

Boucle for

Pour déclarer une boucle il suffit d'utiliser le mot-clé for.

Il existe deux types de boucle for, soit vous connaissez au préalable le nombre d'itérations (par exemple vous savez dès le début qu'un bloc de code va s'exécuter x fois) ou inversement vous n'avez aucune idée du nombre d'itérations de votre bloc de code.

Vous connaissez déjà le nombre d'itérations

Voici comment on déclare une boucle quand vous connaissez antérieurement le nombre d'itérations :

for initialisation ; condition ; itération {
    /* le code qui sera répété */
}

initialisation est une instruction exécutée avant le premier parcours de la boucle for c'est là-bas qu'on initialise le compteur de la boucle (le compteur est une variable temporaire qui est détruite à la sortie de la boucle) suivit d'une condition du compteur dont la valeur déterminera la fin de la boucle, l'itération est l'opération qui déterminera le nombre de répétitions de votre bloc de code.

Imaginez le scénario suivant : "Vous êtes jeune, fainéant et mauvais élève (pas bien !). Votre professeur vous demande alors d'écrire 100 fois la phrase suivante "Je ne dois frapper mes camarades de classe". ça tombe vous êtes en train de suivre un cours sur les boucles 😉 !"

package main

import (
    "fmt"
)

func main() {
    for compteur := 0; compteur < 100; compteur++ {
        fmt.Println(compteur + 1, ") Je ne dois frapper mes camarades de classe")
    }
}

Résultat :

1 ) Je ne dois taper mes camarades de classe
2 ) Je ne dois taper mes camarades de classe
...
99 ) Je ne dois taper mes camarades de classe
100 ) Je ne dois taper mes camarades de classe

Vous ne connaissez pas le nombre d'itérations

Voici comment on déclare une boucle quand vous ne connaissez pas à l'avance le nombre d'itérations :

for condition {
    /* le code qui sera répété */
}

Si la condition est vraie alors on reste dans la boucle sinon on quitte la boucle.

Imaginez le scénario suivant : "Un videur de boîte de nuit refuse l'entrée des mineurs"

package main

import (
    "bufio"
    "fmt"
    "os"
    "strconv"
)

func main() {
    scanner := bufio.NewScanner(os.Stdin)
    var age int

    for age < 18 { // on quitte la boucle s'il est majeur
        fmt.Print("Entrez votre age : ")
        scanner.Scan()
        age, _ = strconv.Atoi(scanner.Text())
    }

    fmt.Println("Bienvenue en boite de nuit !")
}

Résultat :

Entrez votre age : 17
Entrez votre age : 19
Bienvenue en boite de nuit

break et continue

Pour manipuler vos boucles infinies il peut être intéressant d'utiliser les deux mots-clés suivants :

  • break : Interrompre une boucle
  • continue : Revenir au début de la boucle

Imaginons le scénario suivant : "Vous avez bien envie de jouer à un jeu hasard mais le problème c'est que vous n'avez pas assez d'argent 😢 par contre vous avez votre compilateur go 😉."

Vous n'avez pas d'argent ? Pas de panique les boucles infinies vont vous aider à sortir de cette crise !

package main

import (
    "bufio"
    "fmt"
    "math/rand"
    "os"
    "strconv"
    "time"
)

func main() {

    rand.Seed(time.Now().UnixNano())
    randomInt := rand.Intn(10)

    scanner := bufio.NewScanner(os.Stdin)

    max := 20

    for true { // boucle infinie
        fmt.Print("Entrez votre nombre : ")
        scanner.Scan()
        nbr, err := strconv.Atoi(scanner.Text())

        if err != nil {
            fmt.Println("Entrez un nombre !")
            continue // on revient au début de la boucle
        }
        if nbr > max || nbr < 0 {
            fmt.Println("Votre nombre doit être compris entre 0 et ", max, " !")
            continue
        } else if nbr == randomInt {
            fmt.Println("Bien joué !")
            break // on quitte la boucle
        } else {
            fmt.Println("Dommage !")
        }
    }
}

Résultat :

Entrez votre nombre : 50
Votre nombre doit être compris entre 0 et  20  !
Entrez votre nombre : arnaque
Entrez un nombre !
Entrez votre nombre : 6
Dommage !
Entrez votre nombre : 15
Dommage !
Entrez votre nombre : 3
Bien joué !

Espace commentaire

Écrire un commentaire

Rejoignez la discussion

Vous devez être connecté pour poster un message.

33 commentaires

ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Oui, mais fais gaffe, dans un switch, le break sort du switch, pas de la boucle parente. Pour sortir de la boucle, faut utiliser un label.

31/03/2019 à 17:53
marine81
Membre Actif
Avatar de marine81
marine81
Membre Actif

Le break marche aussi dans les switch ?

31/03/2019 à 10:27
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Ajoute un compteur avant la boucle et casse avec un break si tentatives > 5.

31/03/2019 à 01:38
delorme-noel
Membre Actif
Avatar de delorme-noel
delorme-noel
Membre Actif

Comment je peux limiter le nombre de tentatives dans mon jeu de devinette ?

30/03/2019 à 20:43
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

De rien. Le code doit rester lisible. Si tu dois commenter une boucle, c'est qu'elle est probablement mal écrite.

30/03/2019 à 14:48

Très intéressant! Mais une question subsiste : dans le dernier TP, on écrit :

  randomInt := rand.Intn(10)
max := 20   

D'après ce que je comprends, la première ligne génère un nombre aléatoire entre 0 &amp; 10, dans la seconde ligne, on définit un max à 20, qui ne sera donc jamais atteint. Ne serait-il pas mieux de faire ainsi de cette manière :

  max := 20
randomInt := rand.Intn(max)   

Petites update à faire cependant : L'usage de Seed est dépréciée d'après ce que j'ai lu, donc on peut l'enlever

30/03/2019 à 12:21
xjacques
Membre Actif
Avatar de xjacques
xjacques
Membre Actif

Merci pour l'article, simple et efficace. Pas besoin de 300 pages pour comprendre une boucle.

30/03/2019 à 08:55
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

C'est dangereux. Tu risques de créer une boucle infinie si tu fais pas gaffe. Évite au max.

30/03/2019 à 03:20
emilie01
Membre Actif
Avatar de emilie01
emilie01
Membre Actif

J'ai essayé de modifier le compteur à l'intérieur de la boucle, c'est une bonne pratique ?

29/03/2019 à 20:11
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Utilise rand.New(rand.NewSource(time.Now().UnixNano())) pour créer un générateur local.

29/03/2019 à 15:01
patrick81
Membre Actif
Avatar de patrick81
patrick81
Membre Actif

Le rand.Seed est déprécié dans les nouvelles versions de Go, on fait comment maintenant ?

29/03/2019 à 07:15
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Exactement. Elle est locale au bloc de la boucle. C'est propre pour éviter de polluer le scope global.

28/03/2019 à 23:37
paulette-bouvet
Membre Actif
Avatar de paulette-bouvet
paulette-bouvet
Membre Actif

La portée de la variable déclarée dans le for, elle meurt bien après le bloc ?

28/03/2019 à 19:10
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Vérifie ton scanner.Text(). Il contient peut-être des espaces parasites. Fais un strings.TrimSpace.

28/03/2019 à 12:07
bodin-ines
Membre Actif
Avatar de bodin-ines
bodin-ines
Membre Actif

J'ai testé l'exemple du videur de boîte, mais la boucle ne s'arrête jamais même en tapant 18. Une idée ?

28/03/2019 à 05:51
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

@tina-arouna merci !

28/03/2019 à 03:14
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Non, ça n'existe pas. Tu fais un for { ... if condition { break } } et t'as exactement le même comportement.

28/03/2019 à 01:42
marianne31
Membre Actif
Avatar de marianne31
marianne31
Membre Actif

Y'a un équivalent au do-while en Go ?

27/03/2019 à 20:15
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Faut tester l'erreur renvoyée par strconv.Atoi. Regarde :

if err != nil { 
  fmt.Println("C'est pas un nombre ça !") 
  continue 
}
27/03/2019 à 15:58
laure-fontaine
Membre Actif
Avatar de laure-fontaine
laure-fontaine
Membre Actif

Mon programme crash quand je passe des lettres au lieu d'un nombre. Comment gérer ça proprement avec le continue ?

27/03/2019 à 10:29
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

À ne jamais faire. Les flottants sont imprécis. Utilise des entiers et divise ensuite si besoin.

27/03/2019 à 05:57
agomes
Membre Actif
Avatar de agomes
agomes
Membre Actif

Question bête : on peut utiliser des flottants dans l'initialisation de la boucle for ?

27/03/2019 à 01:10
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

T'as sûrement le caractère de nouvelle ligne qui traîne dans ton input. Utilise strings.TrimSpace avant de convertir.

26/03/2019 à 20:08
tbrunel
Membre Actif
Avatar de tbrunel
tbrunel
Membre Actif

Je galère avec le strconv.Atoi dans la boucle de saisie. Il me renvoie toujours une erreur même avec un entier.

26/03/2019 à 12:24
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Oui, le continue te renvoie direct à l'évaluation de la condition. Si ton incrémentation est en fin de bloc, elle est skippée.

26/03/2019 à 04:35

Rejoindre la communauté

Recevoir les derniers articles gratuitement en créant un compte !

S'inscrire