Contactez-nous

Boucles (for, range)

Maîtrisez les boucles en Go avec ce guide exhaustif ! Explorez TOUTES les facettes de la boucle 'for' et du mot-clé 'range' : syntaxes, cas d'usage, itération sur collections et contrôle de boucle. Devenez un expert des répétitions en Go !

Les boucles : Répéter des actions sans se répéter (vous)

En go, comme dans tous les langages de programmation, on a souvent besoin de répéter une action plusieurs fois. Imaginez que vous devez traiter une liste de 1000 clients, envoyer un email à chacun, ou calculer la moyenne de notes pour 50 étudiants. Faire ces actions manuellement serait extrêmement long et répétitif, et source d'erreurs.

C'est là qu'interviennent les boucles, aussi appelées structures répétitives ou itératives. Les boucles sont des structures de contrôle qui permettent d'exécuter un bloc de code plusieurs fois, de manière automatisée et contrôlée. Elles vous évitent d'écrire le même code en boucle (sans boucle !) et rendent vos programmes plus concis, efficaces et faciles à maintenir.

Go, de manière élégante et minimaliste, ne propose qu'une seule instruction de boucle : for. Cependant, cette unique boucle for est extrêmement polyvalente et peut être utilisée pour implémenter tous les types de boucles que l'on retrouve dans d'autres langages : boucles classiques avec compteur, boucles conditionnelles (type 'while'), boucles infinies, et boucles d'itération sur des collections de données.

En plus de la boucle for, Go offre le mot-clé range, qui est souvent utilisé en combinaison avec for pour itérer facilement sur différents types de collections de données comme les tableaux, les slices, les maps, les chaînes de caractères, et même les canaux (channels).

Dans ce chapitre, nous allons explorer en profondeur la boucle for et le mot-clé range en Go. Nous verrons toutes les syntaxes possibles, les différents cas d'utilisation, et comment utiliser les boucles pour automatiser des tâches répétitives et rendre vos programmes plus puissants et flexibles. Maîtriser les boucles est une compétence essentielle pour tout développeur Go !

La boucle `for` classique : répétition contrôlée par un compteur

La forme la plus courante de la boucle for en Go est la boucle `for` classique, qui ressemble aux boucles `for` que l'on retrouve dans d'autres langages comme C, Java ou JavaScript. Elle permet de répéter un bloc de code un nombre de fois déterminé, en utilisant un compteur.

Syntaxe de la boucle `for` classique :

for initialisation; condition; incrémentation {
    // Code à exécuter à chaque itération
}

Fonctionnement de la boucle `for` classique :

  1. Initialisation : Exécutée une seule fois au début de la boucle. On initialise généralement une variable compteur (ex: i := 0).
  2. Condition : Evaluée avant chaque itération. Si la condition est true, le corps de la boucle est exécuté. Si la condition est false, la boucle s'arrête.
  3. Incrémentation/Décrémentation : Exécutée après chaque itération du corps de la boucle. On modifie généralement la variable compteur (ex: i++ pour incrémenter, i-- pour décrémenter).
  4. Corps de la boucle { ... } : Le bloc de code à exécuter à chaque itération, tant que la condition est vraie.

Exemple : Afficher les nombres de 1 à 5 avec une boucle `for` classique.

package main

import "fmt"

func main() {
    for i := 1; i <= 5; i++ { // Initialisation: i = 1, Condition: i <= 5, Incrémentation: i++
        fmt.Println("Nombre :", i) // Code exécuté à chaque itération
    }
}

Dans cet exemple, la boucle for s'exécute 5 fois. La variable i sert de compteur et prend les valeurs 1, 2, 3, 4, et 5. A chaque itération, la fonction fmt.Println affiche la valeur courante de i.

La boucle `for` comme boucle `while` : répétition conditionnelle

La boucle for en Go peut également être utilisée pour implémenter une boucle de type `while`, que l'on retrouve dans d'autres langages. Une boucle `while` répète un bloc de code tant qu'une condition est vraie, sans utiliser de compteur explicite dans la syntaxe de la boucle.

Syntaxe de la boucle for comme while :

for condition { // SEULEMENT la condition (pas d'initialisation ni d'incrémentation)
    // Code exécuté tant que condition est vraie
}

Dans cette forme de boucle for, on ne spécifie que la **condition** après le mot-clé for. L'initialisation et l'incrémentation (ou toute autre modification de la condition) doivent être gérées **manuellement à l'extérieur et à l'intérieur de la boucle**.

Exemple : Compte à rebours de 5 à 1 avec une boucle `for` type `while`.

package main

import "fmt"

func main() {
    compteur := 5 // Initialisation du compteur AVANT la boucle

    for compteur >= 1 { // Condition : compteur >= 1
        fmt.Println("Compte à rebours :", compteur) // Code exécuté tant que la condition est vraie
        compteur-- // Décrémentation manuelle du compteur DANS la boucle
    }
    fmt.Println("Décollage !") // Exécuté après la fin de la boucle
}

Dans cet exemple, la boucle for continue de s'exécuter tant que la variable compteur est supérieure ou égale à 1. La décrémentation de compteur (compteur--) est effectuée **manuellement à l'intérieur du corps de la boucle**, ce qui est typique d'une boucle `while`.

La boucle `for` infinie : répétition sans fin (cas spécifiques)

Go permet également de créer une boucle for infinie, c'est-à-dire une boucle qui se répète indéfiniment, sans condition d'arrêt explicite dans la syntaxe de la boucle. Bien que les boucles infinies soient souvent des erreurs (comme nous l'avons vu précédemment), elles peuvent être utiles dans certains cas spécifiques, notamment pour les programmes qui doivent tourner en continu (serveurs, applications temps réel, etc.).

Syntaxe de la boucle for infinie :

for { // AUCUNE initialisation, condition ou incrémentation
    // Code exécuté en boucle infinie
}

Dans sa forme la plus simple, une boucle for infinie s'écrit simplement avec le mot-clé for suivi d'accolades { ... }, sans aucune initialisation, condition ou incrémentation. Le corps de la boucle est exécuté en continu, sans jamais s'arrêter (sauf si le programme est interrompu de l'extérieur ou si une instruction break est utilisée à l'intérieur de la boucle, comme nous le verrons plus tard).

Exemple : Boucle infinie simulée (avec une pause pour ne pas saturer le processeur).

package main

import (
    "fmt"
    "time" // Package time pour la gestion du temps
)

func main() {
    for { // Boucle infinie
        fmt.Println("En boucle infinie...")
        time.Sleep(1 * time.Second) // Pause d'une seconde (pour éviter de consommer 100% du CPU)
    }
    // Ce code après la boucle ne sera JAMAIS atteint (boucle infinie)
    fmt.Println("Fin du programme")
}

Dans cet exemple, la boucle for infinie affiche le message "En boucle infinie..." en continu, avec une pause d'une seconde entre chaque affichage (grâce à time.Sleep, pour éviter de surcharger le processeur). Sans instruction break ou interruption externe, ce programme continuerait de tourner indéfiniment.

Attention : Les boucles infinies doivent être utilisées avec précaution et seulement lorsque c'est intentionnel et nécessaire. Dans la plupart des cas, vous aurez besoin de boucles qui s'arrêtent à un moment donné !

Le mot-clé `range` : itérer facilement sur des collections de données

Go propose le mot-clé `range`, qui est extrêmement pratique pour itérer sur différents types de collections de données, comme les tableaux (arrays), les tranches (slices), les maps, les chaînes de caractères (strings) et les canaux (channels). Utilisé conjointement avec la boucle for, range simplifie grandement la parcours de ces collections et rend le code plus lisible et concis.

Syntaxe de la boucle for avec range :

for index, valeur := range collection { // 'collection' est un tableau, slice, map, string ou channel
    // Code exécuté pour chaque élément de la collection
    // 'index' est l'index (ou la clé) de l'élément courant (optionnel)
    // 'valeur' est la valeur de l'élément courant
}

Fonctionnement de la boucle for avec range :

  • range collection : Le mot-clé range itère sur les éléments de la collection (tableau, slice, map, string, channel).
  • index, valeur := range ... : A chaque itération, range fournit deux valeurs : index (l'index ou la clé de l'élément courant, qui est optionnel) et valeur (la valeur de l'élément courant). Vous pouvez choisir de ne récupérer que la valeur ou l'index (ou aucun des deux, si vous itérez juste pour répéter une action un certain nombre de fois).
  • Corps de la boucle { ... } : Le code à exécuter pour chaque élément de la collection.

Nous allons maintenant explorer l'utilisation de range avec différents types de collections.

Contrôler le flux des boucles : `break` et `continue`

Go propose deux instructions pour contrôler le flux d'exécution à l'intérieur des boucles : break et continue.

  • break : Permet de sortir immédiatement de la boucle, en interrompant son exécution et en passant à l'instruction suivant la boucle. C'est comme appuyer sur le bouton "stop" d'une chaîne de montage : on arrête immédiatement le processus répétitif.
  • continue : Permet de passer directement à l'itération suivante de la boucle, en ignorant le reste du code du corps de la boucle pour l'itération courante. C'est comme dire à la chaîne de montage : "Ce produit est défectueux, on passe au suivant sans finir le processus sur celui-ci."

Exemples d'utilisation de break et continue :

package main

import "fmt"

func main() {
    for i := 1; i <= 10; i++ {
        if i == 3 {
            continue // Passe à l'itération suivante si i == 3 (n'affiche pas 3)
        }
        if i == 7 {
            break // Sort de la boucle si i == 7 (arrête la boucle)
        }
        fmt.Println("Iteration :", i)
    }
    fmt.Println("Boucle terminée.") // Exécuté après le 'break'
}

Dans cet exemple :

  • Lorsque i vaut 3, l'instruction continue est exécutée, ce qui fait passer directement à l'itération suivante (i devient 4) sans exécuter fmt.Println("Iteration :", i) pour i == 3. Le nombre 3 n'est donc pas affiché.
  • Lorsque i vaut 7, l'instruction break est exécutée, ce qui fait sortir immédiatement de la boucle. L'exécution continue donc après la boucle, et le message "Boucle terminée." est affiché. Les itérations pour i valant 7, 8, 9 et 10 ne sont donc pas exécutées.

Les instructions break et continue permettent d'affiner le contrôle du flux d'exécution des boucles et de gérer des cas particuliers ou des conditions d'arrêt anticipées.

Choisir la bonne boucle : `for` classique ou `for range` ?

Maintenant que vous connaissez les différentes formes de la boucle for et le mot-clé range, comment choisir la boucle la plus appropriée pour chaque situation ?

Quand utiliser la boucle for classique ?

  • Lorsque vous avez besoin d'un compteur explicite et que vous souhaitez contrôler précisément l'initialisation, la condition d'arrêt et l'incrémentation/décrémentation.
  • Lorsque vous itérez sur une plage de nombres, sans forcément parcourir une collection de données (ex: boucle pour répéter une action un certain nombre de fois).
  • Lorsque vous implémentez un algorithme qui nécessite un contrôle fin de l'index de la boucle (bien que `range` fournisse aussi l'index, la boucle for classique offre un contrôle plus direct).
  • Lorsque vous simulez une boucle de type `while` (boucle conditionnelle).

Quand utiliser la boucle for range ?

  • Lorsque vous itérez sur une collection de données (tableau, slice, map, string, channel) et que vous souhaitez accéder facilement aux éléments de cette collection.
  • Lorsque vous n'avez pas besoin de contrôler explicitement un compteur et que vous souhaitez simplement parcourir tous les éléments d'une collection.
  • Lorsque vous voulez écrire du code plus concis et plus lisible pour itérer sur des collections, en évitant la gestion manuelle des indices.
  • Dans la plupart des cas d'itération sur des collections de données en Go, for range est la solution la plus idiomatique et la plus recommandée.

En règle générale, commencez par vous demander si vous itérez sur une collection de données. Si oui, for range est probablement le meilleur choix. Si vous avez besoin d'un contrôle plus fin sur l'itération ou si vous n'itérez pas sur une collection, la boucle for classique sera plus appropriée.

Exercices pratiques : Boucles (for, range) - Répétez l'action, maîtrisez la boucle

Exercice 1 : Table de multiplication avec boucle for classique

Ecrivez un programme go qui demande à l'utilisateur de saisir un nombre entier. Utilisez une boucle for classique pour afficher la table de multiplication de ce nombre de 1 à 10.

Exercice 2 : Somme des éléments d'un slice avec for range

Déclarez un slice de nombres entiers (avec des valeurs de votre choix). Utilisez une boucle for range pour calculer la somme de tous les éléments du slice et affichez la somme.

Exercice 3 : Recherche dans un tableau avec break

Déclarez un tableau de chaînes de caractères (avec des noms de fruits, par exemple). Demandez à l'utilisateur de saisir un nom de fruit à rechercher. Utilisez une boucle for range pour parcourir le tableau et vérifier si le fruit saisi par l'utilisateur est présent dans le tableau. Si le fruit est trouvé, affichez un message "Fruit trouvé !" et utilisez break pour sortir de la boucle immédiatement. Si la boucle se termine sans trouver le fruit, affichez un message "Fruit non trouvé."

Exercice 4 : Filtrage de nombres pairs avec continue

Ecrivez un programme go qui utilise une boucle for classique pour parcourir les nombres de 1 à 20. A l'intérieur de la boucle, utilisez une instruction if et l'opérateur modulo % pour vérifier si le nombre courant est impair. Si le nombre est impair, utilisez continue pour passer à l'itération suivante sans afficher le nombre. Si le nombre est pair, affichez-le.

Exercice 5 (Challenge) : Jeu de devinette avec boucle et nombre limité de tentatives

Ecrivez un programme go qui implémente un jeu de devinette :

  • Le programme choisit un nombre mystère aléatoire entre 1 et 100 (vous pouvez utiliser le package math/rand et time pour générer un nombre aléatoire, cherchez des exemples).
  • Le programme demande à l'utilisateur de deviner le nombre.
  • L'utilisateur a un nombre limité de tentatives (par exemple, 7 tentatives). Utilisez une boucle for classique pour gérer les tentatives.
  • Après chaque tentative, le programme indique à l'utilisateur si le nombre mystère est plus grand ou plus petit que sa proposition.
  • Si l'utilisateur trouve le nombre mystère avant la fin des tentatives, affichez un message de victoire et le nombre de tentatives utilisées. Utilisez break pour sortir de la boucle.
  • Si l'utilisateur ne trouve pas le nombre après toutes les tentatives, affichez un message de défaite et révélez le nombre mystère.

En résumé : les boucles for et range - la puissance de la répétition maîtrisée

Félicitations ! Vous êtes maintenant un expert des boucles en Go ! Vous avez exploré en profondeur :

  • La boucle for classique : pour les répétitions contrôlées par un compteur et les boucles de type `while`.
  • La boucle for infinie : pour les cas spécifiques où une répétition continue est nécessaire.
  • Le mot-clé range : pour itérer facilement sur les tableaux, slices, maps, strings et channels.
  • Les instructions break et continue : pour contrôler finement le flux d'exécution des boucles.

Vous savez désormais comment choisir la boucle la plus adaptée à chaque situation et comment utiliser les boucles pour automatiser des tâches répétitives et rendre vos programmes Go plus efficaces et dynamiques. La puissance de la répétition est maintenant à votre portée ! Continuez à pratiquer, à expérimenter avec les exercices, et vous deviendrez un développeur Go de plus en plus autonome et compétent !