Parcours
/
Go
Go
/
Programme
/
Itération avec `range`
It

Itération avec `range` en Go

1 exercice

À propos de Itération avec `range`

En Go, for range répète un bloc de code pour chaque valeur produite par une expression de range. Cette expression détermine si chaque itération produit une valeur ou deux.

Les expressions de range

Itérer sur un slice

range sur un slice produit l'indice et la valeur de chaque élément, dans l'ordre :

vals := []int{10, 20, 30}
for i, v := range vals {
    fmt.Println(i, v)
}
// 0 10
// 1 20
// 2 30

Itérer sur une map

range sur une map produit chaque clé et chaque valeur, mais l'ordre d'itération n'est pas garanti. Go mélange délibérément l'ordre d'itération des maps, si bien qu'un même programme peut produire une sortie différente à chaque exécution.

hash := map[int]int{9: 10, 99: 20, 999: 30}
for k, v := range hash {
    fmt.Println(k, v)
}
// 99 20
// 999 30
// 9 10

Itérer sur une string

range sur une string produit l'indice d'octet et chaque rune (point de code Unicode). Dans l'exemple suivant, 子 occupe trois octets, donc 猫 commence à l'indice d'octet 3, et non 1.

for i, r := range "子猫" {
    fmt.Println(i, r, string(r))
}
// 0 23376 子
// 3 29483 猫

Si tu as besoin d'indices de rune à la place, convertis la string en une slice de rune :

for i, r := range []rune("子猫") {
    fmt.Println(i, r, string(r))
}
// 0 23376 子
// 1 29483 猫

Itérer sur un entier

range peut itérer directement sur un entier, en produisant les valeurs de 0 jusqu'à cet entier exclu. Les valeurs nulles ou négatives sont valides, mais ne produisent aucune itération.

for n := range 3 {
    fmt.Println(n)
}
// 0
// 1
// 2

Itérer sur un itérateur

range accepte un itérateur de type iter.Seq[V] ou iter.Seq2[K, V]. Un itérateur est une fonction qui produit une séquence de valeurs, une à la fois. range peut alors parcourir ces valeurs.

text := "The quick brown fox"
for word := range strings.FieldsSeq(text) {
    fmt.Println(word)
}
// The
// quick
// brown
// fox

names := []string{"Alice", "Bob", "Vera"}
for i, v := range slices.All(names) {
    fmt.Println(i, ":", v)
}
// 0 : Alice
// 1 : Bob
// 2 : Vera

Itérer sur un canal

Enfin, range peut recevoir les valeurs envoyées dans un canal jusqu'à ce que ce canal soit fermé ailleurs. Les canaux sont traités en détail un peu plus loin dans le programme du parcours.

Omettre l'indice ou la valeur

Go ne compile pas si une variable est déclarée mais jamais utilisée.

vals := []int{10, 20, 30}
for i, v := range vals {
    fmt.Println(v)
}
// Go build failed: declared and not used: i

Si tu n'as besoin que de la valeur, affecte l'indice ou la clé à _ pour l'ignorer.

vals := []int{10, 20, 30}
for _, v := range vals {
    fmt.Println(v)
}
// 10
// 20
// 30

Si tu n'as besoin que de l'indice, omets-le complètement :

vals := []int{10, 20, 30}
for i := range vals {
    fmt.Println(i)
}
// 0
// 1
// 2

Si tu n'as besoin ni de l'indice ni de la valeur, tu peux omettre les deux :

vals := []int{10, 20, 30}
count := 0
for range vals {
    count++
}
// count == 3
Modifie via GitHub Le lien s'ouvre dans une nouvelle fenêtre ou un nouvel onglet

Apprends Itération avec `range`