Existe-t-il une construction foreach
dans le langage Go? Puis-je effectuer une itération sur une tranche ou un tableau en utilisant un for
?
http://golang.org/doc/go_spec.html#For_statements
Une instruction "for" avec une clause "range" parcourt toutes les entrées d'un tableau, d'une tranche, d'une chaîne ou d'une mappe, ou de valeurs reçues sur un canal. Pour chaque entrée, il attribue des valeurs d'itération aux variables d'itération correspondantes, puis exécute le bloc.
Par exemple:
for index, element := range someSlice {
// index is the index where we are
// element is the element from someSlice for where we are
}
Si vous ne vous souciez pas de l'index, vous pouvez utiliser _
:
for _, element := range someSlice {
// element is the element from someSlice for where we are
}
Le trait de soulignement, _
, est le identificateur vide , un espace réservé anonyme.
Itérer sur tablea ou tranche:
// index and value
for i, v := range slice {}
// index only
for i := range slice {}
// value only
for _, v := range slice {}
Itérer sur un carte:
// key and value
for key, value := range theMap {}
// key only
for key := range theMap {}
// value only
for _, value := range theMap {}
Itérer sur un canal:
for v := range theChan {}
Itérer sur un canal équivaut à recevoir depuis un canal jusqu'à sa fermeture:
for {
v, ok := <-theChan
if !ok {
break
}
}
L'exemple suivant montre comment utiliser l'opérateur range
dans une boucle for
pour implémenter une boucle foreach
.
func PrintXml (out io.Writer, value interface{}) error {
var data []byte
var err error
for _, action := range []func() {
func () { data, err = xml.MarshalIndent(value, "", " ") },
func () { _, err = out.Write([]byte(xml.Header)) },
func () { _, err = out.Write(data) },
func () { _, err = out.Write([]byte("\n")) }} {
action();
if err != nil {
return err
}
}
return nil;
}
L'exemple itère sur un tableau de fonctions pour unifier le traitement des erreurs pour les fonctions. Un exemple complet est à Google terrain de je .
PS: cela montre aussi que les suspensions sont une mauvaise idée pour la lisibilité du code. Astuce: la condition for
se termine juste avant l'appel action()
. C'est évident, n'est-ce pas?
Vous pouvez en fait utiliser range
sans référencer ses valeurs de retour en utilisant for range
par rapport à votre type:
arr := make([]uint8, 5)
i,j := 0,0
for range arr {
fmt.Println("Array Loop",i)
i++
}
for range "bytes" {
fmt.Println("String Loop",j)
j++
}
Voici l'exemple de code d'utilisation de foreach dans Golang
package main
import (
"fmt"
)
func main() {
arrayOne := [3]string{"Apple", "Mango", "Banana"}
for index,element := range arrayOne{
fmt.Println(index)
fmt.Println(element)
}
}
Ceci est un exemple en cours d'exécution https://play.golang.org/p/LXptmH4X_
Oui, Plage:
La forme de plage de la boucle for effectue une itération sur une tranche ou une carte.
Lorsque vous parcourez une tranche, deux valeurs sont renvoyées pour chaque itération. Le premier est l'index et le second est une copie de l'élément à cet index.
Exemple :
package main
import "fmt"
var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
func main() {
for i, v := range pow {
fmt.Printf("2**%d = %d\n", i, v)
}
for i := range pow {
pow[i] = 1 << uint(i) // == 2**i
}
for _, value := range pow {
fmt.Printf("%d\n", value)
}
}
Cela peut sembler évident, mais vous pouvez insérer le tableau de la manière suivante:
package main
import (
"fmt"
)
func main() {
for _, element := range [3]string{"a", "b", "c"} {
fmt.Print(element)
}
}
les sorties:
abc