Eine "for" -Anweisung mit einer "range" -Klausel durchläuft alle Einträge eines Arrays, Slice, Strings oder Map oder Werte, die auf einem Kanal empfangen wurden. Für jeden Eintrag werden entsprechende Iterationsvariablen Iterationswerte zugewiesen und anschließend der Block ausgeführt.
Als Beispiel:
for index, element := range someSlice {// index is the index where we are// element is the element from someSlice for where we are}
Wenn Sie sich nicht für den Index interessieren, können Sie Folgendes verwenden _:
for _, element := range someSlice {// element is the element from someSlice for where we are}
Der Unterstrich _ist die leere Kennung , ein anonymer Platzhalter.
In diesem Beispiel elementist dies der Wert des Elements (eine Kopie) - es ist nicht das Element selbst. Obwohl Sie zuweisen können, elementhat dies keine Auswirkungen auf die zugrunde liegende Sequenz.
Nobar
Ich weiß, dass in Python und C häufig Unterstriche als Funktion für die Lokalisierung verwendet werden (dh der gettext ). Würde die Verwendung von Unterstrichen Probleme in Go verursachen? Verwendet Go überhaupt dieselbe Bibliothek für die Lokalisierung?
Sergiy Kolodyazhnyy
2
@SergiyKolodyazhnyy Py docs sagt, dass "(gettext) -Funktion normalerweise wie _()im lokalen Namespace aliasiert ist ", was nur konventionell ist und nicht Teil der Lokalisierungsbibliothek ist. Der Unterstrich _ist eine gültige Bezeichnung, und es ist auch eine Konvention in Go (und Python und Scala und anderen langs), die _für Rückgabewerte zugewiesen wird, die Sie nicht verwenden. Der Umfang von _in diesem Beispiel ist auf den Hauptteil der forSchleife beschränkt. Wenn Sie eine Funktion mit Paketbereich haben, _wird diese im Bereich der for-Schleife schattiert. Es gibt ein paar Pakete für die Lokalisierung, ich habe keine Verwendung _als Funktionsname gesehen.
Davos
149
Go hat eine foreachähnliche Syntax. Es unterstützt Arrays / Slices, Maps und Kanäle.
Iterieren Sie über Array oder Slice :
// index and valuefor i, v := range slice {}// index onlyfor i := range slice {}// value onlyfor _, v := range slice {}
Über eine Karte iterieren :
// key and valuefor key,value:= range theMap {}// key onlyfor key := range theMap {}// value onlyfor _,value:= range theMap {}
Über einen Kanal iterieren :
for v := range theChan {}
Das Iterieren über einen Kanal entspricht dem Empfangen von einem Kanal, bis dieser geschlossen wird:
Obwohl das OP nur nach der Verwendung von Slices gefragt hat, bevorzuge ich diese Antwort, da die meisten letztendlich auch die anderen Verwendungen benötigen werden.
Domoarigato
3
Wichtiger Unterschied zur chanVerwendung: Wenn Sie sich über einen Kanal erstrecken, wird die Schleife ordnungsgemäß verlassen, wenn der Schreiber den Kanal irgendwann schließt. In der for {v := <-theChan}äquivalenten , wird es nicht auf Kanal Schließen beenden. Sie können dies über den zweiten okRückgabewert testen . TOUR
BEISPIEL
Beim Lesen gleich gedacht, for { ... }steht für eine Endlosschleife.
Levite
13
Das folgende Beispiel zeigt, wie der rangeOperator in einer forSchleife zum Implementieren einer foreachSchleife verwendet wird.
Das Beispiel durchläuft ein Array von Funktionen, um die Fehlerbehandlung für die Funktionen zu vereinheitlichen. Ein vollständiges Beispiel finden Sie auf dem Google- Spielplatz .
PS: Es zeigt auch, dass hängende Klammern eine schlechte Idee für die Lesbarkeit von Code sind. Hinweis: Die forBedingung endet kurz vor dem action()Anruf. Offensichtlich, nicht wahr?
Fügen Sie ein hinzu ,und es ist klarer, wo die forBedingung endet: play.golang.org/p/pcRg6WdxBd - Dies ist tatsächlich das erste Mal, dass ich ein Gegenargument zum go fmtStil gefunden habe, danke!
Topskip
@topskip beide sind gültig; wähle einfach die beste aus :)
Filip Haglund
@FilipHaglund Es ist nicht der Punkt, ob es gültig ist. Der Punkt ist, dass IMO es klarer ist, wo die for-Bedingung in diesem speziellen Fall oben endet.
Topskip
8
Meiner Meinung nach ist diese Antwort für die angesprochene Frage unangemessen komplex.
AndreasHassing
@AndreasHassing Wie geht das stattdessen, ohne Redundanz einzuführen?
16.
10
Sie können tatsächlich verwenden, rangeohne auf die Rückgabewerte zu verweisen, indem Sie Folgendes for rangegegen Ihren Typ verwenden:
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++
}
Die Bereichsform der for-Schleife iteriert über ein Slice oder eine Map.
Bei einem Bereich über ein Slice werden für jede Iteration zwei Werte zurückgegeben. Der erste ist der Index und der zweite ist eine Kopie des Elements an diesem Index.
Beispiel:
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)}}
Sie können den Index oder Wert überspringen, indem Sie _ zuweisen.
Wenn Sie nur den Index möchten, löschen Sie den Wert vollständig.
range
In-for
Schleifen wird auch im Abschnitt "Ein Zwischenspiel über Typen" (gegen Ende) des Go-Tutorials erwähnt.Antworten:
https://golang.org/ref/spec#For_range
Als Beispiel:
Wenn Sie sich nicht für den Index interessieren, können Sie Folgendes verwenden
_
:Der Unterstrich
_
ist die leere Kennung , ein anonymer Platzhalter.quelle
element
ist dies der Wert des Elements (eine Kopie) - es ist nicht das Element selbst. Obwohl Sie zuweisen können,element
hat dies keine Auswirkungen auf die zugrunde liegende Sequenz._()
im lokalen Namespace aliasiert ist ", was nur konventionell ist und nicht Teil der Lokalisierungsbibliothek ist. Der Unterstrich_
ist eine gültige Bezeichnung, und es ist auch eine Konvention in Go (und Python und Scala und anderen langs), die_
für Rückgabewerte zugewiesen wird, die Sie nicht verwenden. Der Umfang von_
in diesem Beispiel ist auf den Hauptteil derfor
Schleife beschränkt. Wenn Sie eine Funktion mit Paketbereich haben,_
wird diese im Bereich der for-Schleife schattiert. Es gibt ein paar Pakete für die Lokalisierung, ich habe keine Verwendung_
als Funktionsname gesehen.Go hat eine
foreach
ähnliche Syntax. Es unterstützt Arrays / Slices, Maps und Kanäle.Iterieren Sie über Array oder Slice :
Über eine Karte iterieren :
Über einen Kanal iterieren :
Das Iterieren über einen Kanal entspricht dem Empfangen von einem Kanal, bis dieser geschlossen wird:
quelle
chan
Verwendung: Wenn Sie sich über einen Kanal erstrecken, wird die Schleife ordnungsgemäß verlassen, wenn der Schreiber den Kanal irgendwann schließt. In derfor {v := <-theChan}
äquivalenten , wird es nicht auf Kanal Schließen beenden. Sie können dies über den zweitenok
Rückgabewert testen . TOURfor { ... }
steht für eine Endlosschleife.Das folgende Beispiel zeigt, wie der
range
Operator in einerfor
Schleife zum Implementieren einerforeach
Schleife verwendet wird.Das Beispiel durchläuft ein Array von Funktionen, um die Fehlerbehandlung für die Funktionen zu vereinheitlichen. Ein vollständiges Beispiel finden Sie auf dem Google- Spielplatz .
PS: Es zeigt auch, dass hängende Klammern eine schlechte Idee für die Lesbarkeit von Code sind. Hinweis: Die
for
Bedingung endet kurz vor demaction()
Anruf. Offensichtlich, nicht wahr?quelle
,
und es ist klarer, wo diefor
Bedingung endet: play.golang.org/p/pcRg6WdxBd - Dies ist tatsächlich das erste Mal, dass ich ein Gegenargument zumgo fmt
Stil gefunden habe, danke!Sie können tatsächlich verwenden,
range
ohne auf die Rückgabewerte zu verweisen, indem Sie Folgendesfor range
gegen Ihren Typ verwenden:https://play.golang.org/p/XHrHLbJMEd
quelle
Im Folgenden finden Sie den Beispielcode für die Verwendung von foreach in Golang
Dies ist ein laufendes Beispiel https://play.golang.org/p/LXptmH4X_0
quelle
Ja, Reichweite :
Die Bereichsform der for-Schleife iteriert über ein Slice oder eine Map.
Bei einem Bereich über ein Slice werden für jede Iteration zwei Werte zurückgegeben. Der erste ist der Index und der zweite ist eine Kopie des Elements an diesem Index.
Beispiel:
quelle
Dies mag offensichtlich sein, aber Sie können das Array wie folgt einbinden:
Ausgänge:
https://play.golang.org/p/gkKgF3y5nmt
quelle