Menu

Boucle while en Golang : écrire while et do-while en Go

Go n'a pas de mot-clé while. Une boucle for avec seulement une condition est la boucle while de Go, for sans condition est une boucle infinie, et un do-while est une boucle infinie avec le test à la fin.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Go n'a pas de mot-clé while. Écrivez for suivi d'une condition, et vous avez une boucle while :

La condition est testée avant chaque itération, donc si elle est fausse au départ, le corps ne s'exécute jamais. C'est identique à while (balance < 2000) en C, Java ou JavaScript, sans les parenthèses ni le mot-clé. Les concepteurs de Go ont choisi un seul mot-clé pour toutes les formes de boucle ; voir la page sur la boucle for pour les quatre formes.

while(true) : la boucle infinie

Omettez complètement la condition et la boucle tourne jusqu'à ce que quelque chose à l'intérieur y mette fin :

for { } est l'écriture idiomatique. for true { } compile aussi, mais donne l'impression que l'auteur vient d'un autre langage.

Quatre choses terminent une boucle infinie : break (quitte la boucle), return (quitte la fonction), un panic, et os.Exit. Un programme dont le main reste dans un for {} sans aucune de ces sorties tourne jusqu'à ce qu'on le tue, ce qui est exactement ce qu'il faut pour un serveur ou un worker.

do-while

Un do-while exécute le corps une fois avant de tester la condition. Go n'a pas de syntaxe dédiée. Placez le test à la fin d'une boucle infinie :

Le corps s'exécute au moins une fois quoi qu'il arrive, ce qui est la propriété qui définit le do-while. La source aléatoire utilise une graine fixe pour que la sortie soit la même à chaque exécution ; utilisez rand.IntN sans source avec graine pour un vrai hasard.

Une seconde forme garde la condition dans l'en-tête en forçant le premier passage :

for first := true; first || condition(); first = false {
	// body
}

Elle fonctionne, mais la boucle infinie avec un break à la fin se lit plus facilement, et c'est ce que fait la plupart du code Go.

Lire jusqu'à la fin

La boucle while la plus courante dans le vrai code Go lit une entrée jusqu'à épuisement. bufio.Scanner est conçu pour cela : Scan renvoie false à la fin de l'entrée ou en cas d'erreur, c'est donc la condition de la boucle :

Remplacez strings.NewReader(input) par os.Stdin et la même boucle lit la saisie de l'utilisateur ligne par ligne. Vérifiez scanner.Err() après la boucle : un Scan qui renvoie false ne vous dit pas si l'entrée s'est terminée normalement ou a échoué.

break et continue

Les deux fonctionnent dans toutes les formes de for :

Dans une boucle à condition seule, continue saute directement à la condition. Cela rend facile un bug subtil : si le compteur est mis à jour en bas du corps, un continue placé au-dessus saute la mise à jour et la boucle ne se termine jamais. Mettez le compteur à jour en haut, comme ci-dessus, ou utilisez un for à trois clauses dont l'instruction post s'exécute même après continue.

Attendre quelque chose

Une boucle qui attend une condition doit bloquer ou dormir, pas tourner à vide :

// Wrong: burns a CPU core while waiting
for !ready {
}

// Better: poll with a delay
for !isReady() {
	time.Sleep(100 * time.Millisecond)
}

Interroger en boucle une simple variable qu'une autre goroutine écrit est aussi une data race. Entre goroutines, attendez plutôt sur un channel, un sync.WaitGroup ou un sync.Cond, ou utilisez select avec un timer. Pour les boucles de nouvelles tentatives avec une limite, préférez un for compté pour que la boucle ne puisse pas tourner indéfiniment :

for attempt := 1; attempt <= 5; attempt++ {
	if err := connect(); err == nil {
		break
	}
	time.Sleep(time.Duration(attempt) * 200 * time.Millisecond)
}

Erreurs courantes

  • Oublier de modifier la variable de condition. for i < 10 { fmt.Println(i) } ne se termine jamais. Toute boucle while a besoin de quelque chose dans le corps qui la rapproche de la sortie.
  • Écrire while. while x < 5 {} donne syntax error: unexpected name x at end of statement, parce que while n'est pas un mot-clé ; le compilateur le lit comme un nom ordinaire.
  • Des parenthèses par habitude. for (x < 5) {} compile, et gofmt retire les parenthèses.
  • Déclarer la variable dans la boucle. for n := 10; n > 0 {} est une erreur de syntaxe ; une boucle avec une clause d'initialisation a besoin des trois clauses. Déclarez n avant la boucle, ou écrivez la forme complète à trois clauses.

Questions fréquentes

Go a-t-il une boucle while ?

Pas sous forme de mot-clé. Go utilise for pour toutes les boucles, et un for avec seulement une condition est exactement une boucle while :

for count < 10 {
	count++
}

La condition est testée avant chaque itération, exactement comme while (count < 10) en C ou en Java.

Comment écrire while(true) en Go ?

Écrivez for sans rien derrière : for { ... }. La boucle tourne jusqu'à ce qu'un break, un return, un panic ou os.Exit y mette fin. for true { ... } compile aussi, mais for { } est la forme idiomatique.

Comment écrire une boucle do-while en Go ?

Utilisez une boucle infinie et placez le test de la condition à la fin du corps :

for {
	// body runs at least once
	if !condition {
		break
	}
}

Le corps s'exécute toujours une fois avant que la condition ne soit testée, ce qui est le principe du do-while.

Coddy programming languages illustration

Apprendre à coder avec Coddy

COMMENCER