2011-10-16 13 views
322

Esiste un costrutto foreach nella lingua Go? Posso scorrere su una slice o array usando un for?C'è un ciclo foreach in Go?

+1

check-out: http://groups.google.com/group/golang-nuts/browse_thread/thread/e2966ccdfe910e14? pli = 1 – Kakashi

+1

L'uso di 'range' in' for' loops è citato anche nella sezione "Un interludio sui tipi" (verso la sua fine) del tutorial Go . – kostix

risposta

512

http://golang.org/doc/go_spec.html#For_statements

A "a" economico con un "range" itera clausola di tutte le voci di un array, slice, stringa o carta, o valori ricevuti su un canale. Per ciascuna voce assegna i valori di iterazione alle corrispondenti variabili di iterazione e quindi esegue il blocco.

Per fare un esempio:

for index, element := range someSlice { 
    // index is the index where we are 
    // element is the element from someSlice for where we are 
} 

Se non si preoccupano l'indice, è possibile utilizzare _:

for _, element := range someSlice { 
    // element is the element from someSlice for where we are 
} 

La sottolineatura, _, è il blank identifier, un anonimo segnaposto.

+8

Probabilmente è utile dire che _ è chiamato un identificatore vuoto e ignora semplicemente il valore di ritorno –

8

L'esempio seguente mostra come utilizzare l'operatore range in un ciclo for per implementare un ciclo 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'esempio iterazioni su una serie di funzioni di unificare la gestione delle funzioni di errore. Un esempio completo è su Google's playground.

PS: mostra anche che le parentesi graffe sono una cattiva idea per la leggibilità del codice. Suggerimento: la condizione for termina poco prima della chiamata action(). Ovvio, non è vero?

+3

Aggiungi un ',' ed è più chiaro dove finisce la condizione 'for': http://play.golang.org/p/ pcRg6WdxBd - Questa è davvero la prima volta che ho trovato un contro-argomento per lo stile 'go fmt', grazie! – topskip

+0

@topskip entrambi sono validi fmt; scegli quello migliore :) –

+0

@FilipHaglund Non è il punto se è valido. Il punto è che IMO è più chiaro dove finisce la condizione for in quel caso particolare sopra. – topskip

65

iterare matrice o fetta:

// index and value 
for i, v := range slice {} 

// index only 
for i := range slice {} 

// value only 
for _, v := range slice {} 

iterazioni su una cartina :

// key and value 
for key, value := range theMap {} 

// key only 
for key := range theMap {} 

// value only 
for _, value := range theMap {} 

iterazioni su un canale :

for v := range theChan {} 

Equivalente a:

for { 
    v := <-theChan 
} 
+4

Sebbene l'OP abbia chiesto solo l'utilizzo delle fette, preferisco questa risposta, perché la maggior parte alla fine necessiterà anche degli altri usi. – domoarrigato

+1

importante distinzione sull'uso di 'chan': l'estensione su un canale uscirà con grazia dal ciclo se lo scrittore chiude il canale ad un certo punto. Nel 'for {v: = <-theChan}' _equivalent_, non * uscirà sulla chiusura del canale. Puoi testare questo tramite il secondo valore di ritorno 'ok'. [TOUR EXAMPLE] (https://tour.golang.org/concurrency/4) – colminator

+0

Pensato lo stesso durante la lettura, 'for {...}' indica un ciclo infinito. – Levit

6

È possibile, infatti, utilizzare range senza fare riferimento Si tratta di valori di ritorno utilizzando for range contro il tuo tipo:

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

+2

Buono a sapersi, ma non sarà utile nella maggior parte dei casi – Sridhar

+0

Concordato @Sridhar è una nicchia carina. – robstarbuck

3

seguito è riportato il codice di esempio per come utilizzare foreach in golang

package main 

import (
    "fmt" 
) 

func main() { 

    arrayOne := [3]string{"Apple", "Mango", "Banana"} 

    for index,element := range arrayOne{ 

     fmt.Println(index) 
     fmt.Println(element)   

    } 

} 

Questo è un esempio in esecuzione https://play.golang.org/p/LXptmH4X_0