Introduction
Dans la programmation informatique, une boucle est une structure de code qui permet de répéter l’exécution d’un morceau de code jusqu’à ce qu’une certaine condition soit remplie. L’utilisation de boucles dans la programmation informatique permet d’automatiser et de répéter des tâches similaires plusieurs fois. Imaginez que vous avez une liste de fichiers à traiter ou que vous souhaitez compter le nombre de lignes dans un article. Vous utilisez une boucle dans votre code pour résoudre de telles problématiques.
En Go, une boucle for
implémente l’exécution répétée de code en fonction d’un compteur ou d’une variable de boucle. Contrairement aux autres langages de programmation qui disposent de plusieurs constructes de boucle, tels que while
, do
, etc., Go ne dispose que de la boucle for
. Cela permet de rendre votre code plus clair et plus lisible, car vous n’avez pas à vous soucier de plusieurs stratégies pour obtenir le même résultat de boucle. Cette lisibilité accrue et la charge cognitive réduite lors du développement rendront également votre code moins susceptible d’erreurs que dans d’autres langages.
Dans ce tutoriel, vous apprendrez comment fonctionne la boucle for
en Go, y compris les trois principales variantes de son utilisation. Nous commencerons par montrer comment créer différents types de boucles for
, suivi de la manière de parcourir les types de données séquentielles en Go. Nous terminerons en expliquant comment utiliser des boucles imbriquées.
Déclarer des boucles ForClause et Condition
Pour prendre en compte divers cas d’utilisation, il existe trois méthodes distinctes pour créer des boucles for
en Go, chacune avec ses propres capacités. Ces méthodes sont de créer une boucle for
avec une Condition, une ForClause ou une RangeClause. Dans cette section, nous expliquerons comment déclarer et utiliser les variantes ForClause et Condition.
Commençons par voir comment nous pouvons utiliser une boucle for
avec la ForClause.
Une boucle ForClause est définie par une instruction initiale, suivie de une condition et ensuite d’une instruction postérieure. Elles sont arrangées dans la syntaxe suivante :
for [ Initial Statement ] ; [ Condition ] ; [ Post Statement ] {
[Action]
}
Pour expliquer ce que font les composants précédents, regardons une boucle for
qui incrémente à travers une plage de valeurs spécifiée en utilisant la syntaxe ForClause :
Divisons cette boucle et identifions chaque partie.
La première partie de la boucle est i := 0
. C’est l’instruction initiale :
for i := 0; i < 5; i++ {
fmt.Println(i)
}
Elle indique que nous déclarons une variable appelée i
et affectons sa valeur initiale à 0
.
Ensuite, nous avons la condition :
for i := 0; i < 5; i++ {
fmt.Println(i)
}
Dans cette condition, nous avons déclaré que tant que i
est inférieur à la valeur de 5
, la boucle devrait continuer à s’exécuter.
Enfin, nous avons l’instruction postérieure :
for i := 0; i < 5; i++ {
fmt.Println(i)
}
Dans l’instruction post-test, nous incrémentons la variable de boucle i
de 1 à chaque itération en utilisant l’opérateur i++
d’incrément.
Lorsque nous exécutons ce programme, la sortie ressemble à ceci :
Output0
1
2
3
4
La boucle s’est executée 5 fois. Initialement, elle a défini i
à 0
, puis elle a vérifié si i
était inférieur à 5
. Comme la valeur de i
était inférieure à 5
, la boucle s’est executée et l’action de fmt.Println(i)
a été exécutée. Après l’achèvement de la boucle, l’instruction postérieure de i++
a été invoquée, et la valeur de i
a été incrémentée de 1.
Remarque : Gardez à l’esprit que dans la programmation, nous tendons généralement à commencer à l’index 0, c’est pourquoi bien que 5 nombres soient imprimés, ils vont de 0 à 4.
Nous ne sommes pas limités à démarrer à 0 ou à arrêter à une valeur spécifiée. Nous pouvons assigner n’importe quelle valeur à notre instruction initiale et aussi arrêter à n’importe quelle valeur dans notre instruction postérieure. Cela nous permet de créer n’importe quelle plage désirée pour boucler à travers :
Cette fois, l’itération va de 20 (inclus) à 25 (exclus), donc la sortie ressemble à ceci :
Output20
21
22
23
24
Nous pouvons également utiliser notre instruction postérieure pour incrémenter à des valeurs différentes. Cela est similaire à step
dans d’autres langages :
Premièrement, utilisons une instruction postérieure avec une valeur positive :
for i := 0; i < 15; i += 3 {
fmt.Println(i)
}
Dans ce cas, l’instruction for
est configurée de sorte que les nombres de 0 à 15 s’affichent, mais avec un increment de 3, ce qui signifie que seuls tous les troisièmes nombres sont imprimés, comme suit :
Output0
3
6
9
12
Nous pouvons également utiliser une valeur négative pour l’argument de notre déclaration postérieure à la boucle, mais nous devrons adapter convenablement les arguments de la déclaration initiale et du test d’arrêt correspondants :
ici, nous avons défini i
avec une valeur initiale de 100
, utilisé la condition i < 0
pour arriver à 0
et l’instruction après la déclaration décrementant la valeur par 10 avec le opérateur -=
. La boucle commence à 100
et se termine à 0
, diminuant de 10 avec chaque itération. Vous pouvez voir cela dans la sortie :
Output100
90
80
70
60
50
40
30
20
10
Vous pouvez également exclure la déclaration initiale et l’instruction après la boucle du syntaxe for
et seulement utiliser la clause de condition. Cela est ce qu’on appelle un Boucle conditionnelle :
i := 0
for i < 5 {
fmt.Println(i)
i++
}
Cette fois, nous avons déclaré la variable i
séparément de la boucle précédente dans la ligne de code suivante. La boucle ne possède que la clause de condition qui vérifie si i
est inférieure à 5
. Autant que la condition évalue à true
, la boucle continuera à itérer.
Parfois, vous pouvez ne pas savoir combien de itérations vous devez effectuer pour accomplir une tâche spécifique. Dans ce cas, vous pouvez omettre toutes les instructions, et utiliser le mot-clé break
pour exécuter une sortie :
for {
if someCondition {
break
}
// faire une action ici
}
Un exemple de ceci serait lorsqu’on lit depuis une structure indéterminée comme un buffet et on ne sait pas quand on sera terminé de lire :
Dans le code précédent, buf :=bytes.NewBufferString("one\ntwo\nthree\nfour\n")
déclare un tampon avec certaines données. Comme nous ne savons pas quand le tampon terminera la lecture, nous créons un for
boucle sans clause. Dans l’intérieur de la boucle for
, nous utilisons line, err := buf.ReadString('\n')
pour lire une ligne depuis le tampon et vérifier s’il y avait une erreur lors de la lecture depuis le tampon. Si oui, nous traitons l’erreur, et utilisons le mot-clé break
pour quitter la boucle for
. Avec ces break
points, vous n’avez pas besoin d’inclure une condition pour arrêter la boucle.
Dans cette section, nous avons appris comment déclarer une boucle ForClause et l’utiliser pour iterrer à travers une plage de valeurs connues. Nous avons également appris comment utiliser une boucle Condition pour iterrer jusqu’à ce qu’une condition spécifique soit remplie. La prochaine fois, nous apprendrons comment utiliser la RangeClause pour iterrer à travers les types de données séquentiels.
Itérer à travers les types de données séquentiels avec RangeClause
Il est courant en Go d’utiliser des boucles for
pour iterrer sur les éléments des types de données séquentiels ou collectifs tels que les slices, les tableaux et les chaînes de caractères. Pour faciliter cela, nous pouvons utiliser une boucle for
avec une syntaxe de RangeClause. Si vous pouvez itérer sur les types de données séquentiels en utilisant la syntaxe ForClause, la RangeClause est plus propre et plus lisible.
Avant d’examiner l’utilisation de la RangeClause, voyons comment nous pouvons itérer à travers un slice en utilisant la syntaxe ForClause :
package main
import "fmt"
func main() {
sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}
for i := 0; i < len(sharks); i++ {
fmt.Println(sharks[i])
}
}
Exécuter cela donnera les résultats suivants, imprimant chaque élément du slice :
Outputhammerhead
great white
dogfish
frilled
bullhead
requiem
Maintenant, essayons d’utiliser la RangeClause pour effectuer les mêmes actions :
package main
import "fmt"
func main() {
sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}
for i, shark := range sharks {
fmt.Println(i, shark)
}
}
Dans ce cas, nous imprimons chaque élément de la liste. Bien que nous avons utilisé les variables i
et requin
, nous aurions pu appeler la variable n’importe quelle autre nom de variable valide et nous aurions obtenu la même sortie :
Output0 hammerhead
1 great white
2 dogfish
3 frilled
4 bullhead
5 requiem
Lors de l’utilisation de range
sur un slice, elle retournera toujours deux valeurs. La première valeur sera l’index à l’itération actuelle de la boucle, et la seconde est la valeur à cet index. Dans ce cas, pour la première itération, l’index était 0
et la valeur était hachet
.
Parfois, nous voulons seulement la valeur des éléments de la séquence, pas l’index. Si nous changions le code précédent pour ne pas imprimer la valeur cependant, nous recevrons une erreur de compilation :
package main
import "fmt"
func main() {
sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}
for i, shark := range sharks {
fmt.Println(shark)
}
}
Outputsrc/range-error.go:8:6: i declared and not used
Car i est déclaré dans la boucle for, mais n’est jamais utilisé, la compilatrice répondra avec l’erreur de i déclaré et non utilisé. Cela est également le même type d’erreur que vous recevez en Go toutes les fois que vous déclarez une variable et ne l’utilisez pas.
Du fait de cela, Go possède l’identificateur blanc qui est un traitement sous-ligne (_
). Dans une boucle for, vous pouvez utiliser l’indicateur blanc pour ignorer toute valeur retournée par la syntaxe range. En ce cas, nous voulons ignorer l’index, qui est le premier argument renvoyé.
package main
import "fmt"
func main() {
sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}
for _, shark := range sharks {
fmt.Println(shark)
}
}
Outputhammerhead
great white
dogfish
frilled
bullhead
requiem
Ceci montre que la boucle itérative a traversé chaque élément de la séquence sans l’index.
Vous pouvez également utiliser range
pour ajouter des éléments à une liste :
package main
import "fmt"
func main() {
sharks := []string{"hammerhead", "great white", "dogfish", "frilled", "bullhead", "requiem"}
for range sharks {
sharks = append(sharks, "shark")
}
fmt.Printf("%q\n", sharks)
}
Output['hammerhead', 'great white', 'dogfish', 'frilled', 'bullhead', 'requiem', 'shark', 'shark', 'shark', 'shark', 'shark', 'shark']
ici, nous avons ajouté une chaine de caractères de remplacement de "shark"
pour chaque élément de la longueur de la séquence sharks
.
Noticez que nous n’avons pas besoin d’utiliser l’indicateur blanc _
pour ignorer toute valeur de retour de la syntaxe range. Go permet également de laisser complètement déclarer la partie du range si vous ne voulez pas utiliser ni l’index ni la valeur de retour.
Nous pouvons également utiliser l’opérateur range
pour remplir des valeurs dans une liste :
package main
import "fmt"
func main() {
integers := make([]int, 10)
fmt.Println(integers)
for i := range integers {
integers[i] = i
}
fmt.Println(integers)
}
Dans cet exemple, la slice entiers
est initialisée avec dix valeurs vides, mais le for
loop configure toutes les valeurs de la liste comme suit :
Output[0 0 0 0 0 0 0 0 0 0]
[0 1 2 3 4 5 6 7 8 9]
La première fois que nous imprimons la valeur de la slice entiers
, nous voyons tous les zéros. Ensuite, nous parcourons chaque index et définissons la valeur à l’index courant. En imprimant ensuite la valeur de entiers
pour la deuxième fois, nous montrons que toutes les valeurs sont maintenant égales à 0
à 9
.
Nous pouvons également utiliser l’opérateur range
pour parcourir chaque caractère dans une chaîne :
OutputS
a
m
m
y
Lorsque nous parcourons un map, range
retourne à la fois la clé et la valeur :
Outputcolor: blue
location: ocean
name: Sammy
animal: shark
Note : Il est important de noter que l’ordre dans lequel un map retourne est aléatoire. Chaque fois que vous exécutez ce programme, vous pourriez obtenir un résultat différent.
Maintenant que nous avons appris comment parcourir les données séquentielles avec des boucles for
range
, voyons comment utiliser des boucles à l’intérieur de boucles.
Boucles imbriquées
Les boucles peuvent être imbriquées en Go, à l’image de d’autres langages de programmation. L’imbrication se produit lorsque nous avons un constructeur à l’intérieur d’un autre. Dans ce cas, une boucle imbriquée est une boucle qui se produit à l’intérieur d’une autre boucle. Ces boucles imbriquées peuvent être utiles lorsque nous souhaitons que une action répétée soit effectuée sur chaque élément d’un ensemble de données.
Les boucles imbriquées sont structurellement semblables aux instructions if
imbriquées. Elles sont construites de la manière suivante :
for {
[Action]
for {
[Action]
}
}
Le programme rencontre d’abord la boucle externe, exécutant sa première itération. Cette première itération déclenche l’intérieure, imbriquée, qui est ensuite complétée. Ensuite, le programme retourne en haut de la boucle externe, complétant la deuxième itération et déclenchant à nouveau l’imbriquée. Encore une fois, l’imbriquée est complétée, et le programme retourne en haut de la boucle externe jusqu’à ce que la séquence soit complétée ou qu’une instruction break ou une autre arrête le processus.
Allons implémenter une boucle for
imbriquée pour examiner plus précisément. Dans cet exemple, la boucle externe itère à travers un tableau d’entiers appelé numList
, et l’intérieure itère à travers un tableau de chaînes de caractères appelé alphaList
.
Lorsque nous exécuterons ce programme, nous recevons la sortie suivante :
Output1
a
b
c
2
a
b
c
3
a
b
c
Le programme effectue la première itération de boucle externe en affichant 1
, ce qui déclenche ensuite la fin de la boucle interne, en affichant successivement a
, b
, c
. Une fois que la boucle interne est terminée, le programme revient au début de la boucle externe, affiche 2
, puis à nouveau affiche toute la boucle interne (a
, b
, c
), etc.
Des boucles imbriquées peuvent être utiles pour iterer sur des éléments provenant d’une séquence composée de séquences. En utilisant juste une boucle for
, le programme affichera chaque liste interne comme un seul élément :
Output[0 1 2]
[-1 -2 -3]
[9 8 7]
Pour accéder à chacun des éléments contenus dans les listes internes, nous implémenterons une boucle imbriquée :
Output0
1
2
-1
-2
-3
9
8
7
Lorsque nous utilisons une boucle imbriquée ici, nous pouvons iterer sur les éléments individuels contenus dans les sous-séquences.
Conclusion
Dans cette tutorielle, nous avons appris comment déclarer et utiliser des boucles for
pour résoudre des tâches répétitives en Go. Nous avons également découvert les trois différentes variantes de la boucle for
et quand les utiliser. Pour en savoir plus sur les boucles for
et comment contrôler le flux d’elles, lisez Utiliser Break et Continue lorsque vous travaillez avec des boucles en Go.
Source:
https://www.digitalocean.com/community/tutorials/how-to-construct-for-loops-in-go