web-dev-qa-db-fra.com

Existe-t-il une boucle foreach dans Go?

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?

480
tatsuhirosatou

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.

729
Keith Thompson

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
    }
}
120
Moshe Revah

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?

12
ceving

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++
}

https://play.golang.org/p/XHrHLbJMEd

10
robstarbuck

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_

8
Nisal Edu

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)
    }
}
  • Vous pouvez ignorer l'index ou la valeur en attribuant à _.
  • Si vous ne voulez que l'index, supprimez entièrement la valeur.
3
Amitesh

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

https://play.golang.org/p/gkKgF3y5nmt

1
jpihl