Tutoriel Golang For Loop [With Examples]



Explorez les arcanes des boucles en Golang à travers une série d’exemples pratiques.

L’ascension fulgurante de langages tels que Rust, Golang et TypeScript n’a échappé à personne dans le monde du développement. Si le développement back-end ou DevOps vous attire, la maîtrise de Golang s’avère un atout indéniable.

Pour tout débutant souhaitant s’approprier les bases d’un langage de programmation, la compréhension des boucles est une étape incontournable.

Golang se distingue par son approche minimaliste en ne proposant que la boucle `for`. Nous allons décortiquer cette unique boucle et explorer comment elle permet de simuler d’autres types de boucles.

C’est parti !

Structure de la boucle `for` en Golang

La syntaxe pour créer une boucle `for` en Golang est la suivante :

for initialisation; condition; mise à jour {
    // Instructions à exécuter
}

Où :

  • `initialisation` définit l’initialisation de la variable utilisée dans la boucle.
  • `condition` est l’expression qui détermine si le bloc de code de la boucle doit continuer à s’exécuter. Tant que cette condition est vraie, le bloc est exécuté. L’exécution de la boucle prend fin lorsque la condition devient fausse.
  • `mise à jour` est une instruction qui modifie la variable de boucle, généralement pour l’incrémenter ou la décrémenter.

💡 Notez la similitude avec la boucle `for` en C, à l’exception de l’absence de parenthèses.

Voici le déroulement typique d’une boucle `for` en Golang :

Passons à la pratique avec quelques exemples concrets. ⏰ Vous pouvez expérimenter soit dans votre environnement local avec Golang installé, soit sur Go Playground.

Cas pratiques de la boucle `for` en Golang

Mettons en œuvre la syntaxe que nous venons de voir. Voici une boucle `for` qui affiche les nombres de 1 à 5, avec une incrémentation de un à chaque étape.

package main

import "fmt"

func main() {
	fmt.Println("Boucle for:")
	num := 5
	for i := 1; i <= num; i++ {
		fmt.Println(i)
	}
}

Nous initialisons `i` à 1, la condition est `i <= 5`, et nous incrémentons `i` de 1 après chaque itération. Le résultat est le suivant :

//Sortie
Boucle for:
1
2
3
4
5

Voici un autre exemple. Cette boucle démarre à 5 et décompte jusqu’à 1, tant que la variable de boucle est supérieure ou égale à 1. Nous décrémentons donc la variable de boucle de 1 à chaque itération.

package main

import "fmt"

func main() {
	fmt.Println("Boucle for:")
	num := 5
	for i := num; i >= 1; i-- {
		fmt.Println(i)
	}
}

Le résultat attendu :

//Sortie
Boucle for:
5
4
3
2
1

Quelle est la portée de la variable de boucle ?

La portée d’une variable de boucle est limitée au bloc de la boucle `for` lui-même. Elle n’est pas accessible en dehors.

Pour le vérifier, tentons d’accéder à `i` en dehors de sa boucle :

package main

import "fmt"

func main() {
	fmt.Println("Boucle for:")
	num := 5
	for i := 1; i <= num; i++ {
		fmt.Println(i)
	}
	fmt.Println(i)

}

L’erreur est prévisible : `i` est inconnu (sa portée est restreinte à la boucle `for`) :

// Sortie
./prog.go:11:14: undefined: i

La boucle `for` infinie en Golang

Est-il possible de créer des boucles `for` infinies en Go ? Absolument !

Si l’on examine le déroulement d’une boucle `for` :

  • Le bloc d’instructions s’exécute tant que la condition est vraie.
  • L’exécution de la boucle s’arrête quand la condition devient fausse.
  • En conséquence, si la condition ne devient jamais fausse (ou est toujours vraie), nous avons affaire à une boucle infinie.

Il est possible d’utiliser `for` sans initialisation, condition ni mise à jour sans générer d’erreur de syntaxe. Cela nous permet de créer une boucle infinie :

package main

import "fmt"

func main() {
	for {
	   fmt.Println("en cours...")
	}
}
//Sortie
en cours...
en cours...
en cours...
en cours...
en cours...
//et cela continue indéfiniment !

Dans cet exemple, `num` est initialisé à 5. La condition est `num > 0`. La boucle s’exécutera donc tant que `num` sera supérieur à zéro.

package main

import "fmt"

func main() {
	num := 5
	for num > 0 {
		fmt.Println(num)
	}
}

Puisque la valeur de `num` ne change jamais, la condition reste toujours vraie et la boucle tourne à l’infini !

//Sortie
5
5
5
5
5
5
//et cela continue indéfiniment !

Puisque `for` est la seule structure de boucle en Golang, nous allons maintenant voir comment émuler les boucles `while` et `do-while` avec `for`.

Émuler la boucle `while` avec la boucle `for`

Une boucle `while` classique se présente ainsi :

// initialisation de la variable de boucle
while (condition){
    // instructions à exécuter
    // mise à jour de la variable de boucle
} 

Rappelez-vous de la boucle `for` infinie que nous avons écrite précédemment : elle ne comportait pas d’initialisation, de condition ni de mise à jour.

for {
// la plus simple des boucles infinies
}

Nous pouvons donc adapter la boucle `for` pour qu’elle ne contienne que la condition (de cette manière) afin d’imiter une boucle `while` :

//initialisation de la variable de boucle
for condition {
 // instructions à exécuter
 // mise à jour de la variable de boucle
}

Voici l’équivalent d’une boucle `while` utilisant notre première boucle `for` :

package main

import "fmt"

func main() {
	fmt.Println("Émulation de boucle while")
	num := 5
	for num > 0 {
		fmt.Println(num)
		num--
	}
}
//Sortie
Émulation de boucle while
5
4
3
2
1

Émuler la boucle `do-while` avec la boucle `for`

Si vous avez déjà programmé en C ou un langage similaire, vous connaissez la structure `do-while` :

// initialisation de la variable de boucle
do {
//instructions
// mise à jour de la variable de boucle
} while(condition);

La principale distinction entre `while` et `do-while` est que `while` évalue la condition avant d’entrer dans la boucle, tandis que `do-while` la vérifie après l’exécution du bloc d’instructions.

Ainsi, avec une boucle `while`, si la condition est immédiatement fausse, le bloc d’instructions ne s’exécutera jamais. Dans une boucle `do-while`, le bloc d’instructions sera exécuté au moins une fois, même si la condition est fausse.

En gardant cela à l’esprit, nous pouvons imiter le comportement d’une boucle `do-while` :

  • Créer une boucle `for` infinie.
  • Utiliser une condition `if` pour sortir de la boucle quand la condition est respectée.

Supposons que vous souhaitiez utiliser une boucle `do-while` où le bloc d’instructions doit s’exécuter tant que `num` est inférieur à 0. Nous pouvons donc créer une boucle `for` et sortir de la boucle lorsque `num` est supérieur ou égal à 0.

package main

import "fmt"

func main() {
	fmt.Println("Émulation de boucle do-while")
	num := 5
	for {
		fmt.Println("la boucle s'exécute...")
		if num >= 0 {
			break
		}
	}
}

💡 Notez que l’exécution de la boucle si `num` < 0 et la sortie de la boucle si `num` >= 0 sont des conditions équivalentes.

Même si la condition `num` > 0 est initialement fausse (car `num` vaut 5), le bloc d’instructions s’exécutera une fois, imitant une boucle `do-while`.

//Sortie
Émulation de boucle do-while
la boucle s'exécute...

Parcourir les tableaux avec la boucle `for`

En Golang, lors du parcours de tableaux avec une boucle `for` et `range`, vous pouvez accéder à la fois aux index et aux éléments. Cela fonctionne de la même manière que `enumerate` en Python.

Ici, nous créons `numArray`, un tableau d’entiers. Nous le parcourons ensuite avec une boucle `for` :

package main

import "fmt"

func main() {
	fmt.Println("Parcours d'un tableau")
	numArray := []int{3, 7, 0, 10, 8, 9}
	for idx, num := range numArray {
		fmt.Println("À l'index", idx, ": ", num)
	}
}

Comme nous pouvons le voir, nous pouvons accéder simultanément à l’index et à l’élément de chaque position :

//Sortie
Parcours d'un tableau
À l'index 0 :  3
À l'index 1 :  7
À l'index 2 :  0
À l'index 3 :  10
À l'index 4 :  8
À l'index 5 :  9

Utilisation de `defer` dans une boucle `for` en Golang

Le mot-clé `defer` en Golang permet de différer l’exécution d’une fonction.

Principalement utilisé pour des opérations de nettoyage de ressources ou de gestion d’erreurs, il est intéressant de comprendre son comportement dans une boucle `for`. Voyons ce qui se passe lorsque nous utilisons `defer` dans une boucle `for` pour différer les appels à `Println()`.

package main

import "fmt"

func main() {
	fmt.Println("Boucle for:")
	num := 5
	for i := 1; i <= num; i++ {
		defer fmt.Println(i)
	}
}

💬 Lorsqu’un appel de fonction est différé, il est ajouté à une pile et exécuté dans l’ordre inverse (LIFO). Cette exécution n’a lieu qu’après le retour de la fonction qui contient l’instruction `defer`.

Par conséquent, `fmt.Println(5)` est exécuté en premier et `fmt.Println(1)` en dernier :

//Sortie
Boucle for:
5
4
3
2
1

Conclusion

Voici un récapitulatif des points clés abordés dans ce tutoriel :

  • En Golang, une boucle `for` est créée avec la syntaxe `for initialisation; condition; mise à jour { //corps de la boucle}`.
  • Le déroulement de la boucle `for` est simple : la variable de boucle est initialisée, la condition détermine si le corps de la boucle s’exécute, et la mise à jour modifie la variable après chaque itération.
  • La portée de la variable de boucle est limitée au corps de la boucle. Elle n’est pas accessible en dehors.
  • Bien que Golang ne propose que la boucle `for`, il est possible d’émuler les comportements des boucles `while` et `do-while` avec des astuces.
  • D’autres applications de la boucle `for` incluent le parcours de tableaux et l’utilisation de `defer` dans le corps de la boucle.

N’hésitez pas à vous familiariser avec l’utilisation des boucles `for` en Python. Bonne continuation ! 🎉