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 les 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 l' identificateur vide , un espace réservé anonyme.
Dans cet exemple, elementest la valeur de l'élément (une copie) - ce n'est pas l'élément lui-même. Bien que vous puissiez l'assigner à element, cela n'affectera pas la séquence sous-jacente.
nobar
Je sais qu'en Python et C, il est fréquent d'utiliser le soulignement comme fonction de localisation (c'est-à-dire le gettext ). L'utilisation du trait de soulignement causerait-il des problèmes dans Go? Go utilise-t-il même la même bibliothèque pour la localisation?
Sergiy Kolodyazhnyy
3
@SergiyKolodyazhnyy Py docs dit que "la fonction (gettext) est généralement aliasée comme _()dans l'espace de noms local" ce qui est juste par convention , cela ne fait pas partie de la lib de localisation. Le trait de soulignement _est une étiquette valide, et c'est également une convention dans Go (et Python et Scala et d'autres langs) à affecter aux _valeurs de retour que vous n'utiliserez pas. La portée de _dans cet exemple est limitée au corps de la forboucle. Si vous avez une fonction de portée de package, _elle sera alors masquée dans la portée de la boucle for. Il y a quelques paquets pour la localisation, je n'ai vu aucune utilisation _comme nom de fonction.
Davos
150
Go a une foreachsyntaxe similaire à. Il prend en charge les tableaux / tranches, les cartes et les canaux.
Itérer sur un tableau ou une tranche :
// index and valuefor i, v := range slice {}// index onlyfor i := range slice {}// value onlyfor _, v := range slice {}
Itérer sur une carte :
// key and valuefor key,value:= range theMap {}// key onlyfor key := range theMap {}// value onlyfor _,value:= range theMap {}
Itérer sur un canal :
for v := range theChan {}
Itérer sur un canal équivaut à recevoir d'un canal jusqu'à ce qu'il soit fermé:
Bien que l'OP ne demande que l'utilisation des tranches, je préfère cette réponse, car la plupart auront également besoin des autres utilisations.
domoarigato
3
distinction importante à propos de l' chanutilisation: le fait de parcourir un canal quittera gracieusement la boucle si l'écrivain ferme le canal à un moment donné. Dans l' for {v := <-theChan}équivalent , il ne sortira pas à la fermeture du canal. Vous pouvez le tester via la deuxième okvaleur de retour. EXEMPLE DE TOUR
colm.anseo
Pensé de même lors de la lecture, for { ... }représente une boucle infinie.
Lévite
13
L'exemple suivant montre comment utiliser l' rangeopérateur dans une forboucle pour implémenter une foreachboucle.
L'exemple parcourt un tableau de fonctions pour unifier la gestion des erreurs pour les fonctions. Un exemple complet est sur le terrain de jeu de Google .
PS: cela montre aussi que les accolades suspendues sont une mauvaise idée pour la lisibilité du code. Astuce: la forcondition se termine juste avant l' action()appel. Évident, non?
Ajoutez un ,et il est plus clair où la forcondition se termine: play.golang.org/p/pcRg6WdxBd - C'est en fait la première fois que je trouve un contre-argument au go fmtstyle, merci!
topskip
@topskip les deux sont valides fmt; choisissez le meilleur :)
Filip Haglund
@FilipHaglund Ce n'est pas la question s'il est valide. Le fait est que l'OMI est plus clair où la condition for se termine dans ce cas particulier ci-dessus.
topskip
9
À mon avis, cette réponse est déraisonnablement complexe pour la question ciblée.
AndreasHassing
@AndreasHassing Comment faire à la place sans introduire de redondance?
ceving
10
Vous pouvez en fait utiliser rangesans référencer ses valeurs de retour en utilisant for rangecontre 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++
}
Parfois, c'est l'exemple le plus simple qui est le plus utile. Merci! Je n'ai rien contre les réponses les plus ésotériques des autres commentateurs - elles illustrent certainement les subtilités d'une programmation Go très idiomatique, au point qu'elles deviennent ... illisibles et difficiles à suivre - mais je préfère votre réponse: elle va directement au cœur avec l'exemple le plus simple possible (qui fonctionne et il est évident pourquoi cela fonctionne).
Gwyneth Llewelyn
4
Oui, plage :
La forme de plage de la boucle for itère sur une tranche ou une carte.
Lors d'une plage sur 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 l'affectant à _.
Si vous souhaitez uniquement l'index, supprimez entièrement la valeur.
range
infor
est également mentionnée dans la section "Interlude sur les types" (vers la fin) du didacticiel Go.Réponses:
https://golang.org/ref/spec#For_range
Par exemple:
Si vous ne vous souciez pas de l'index, vous pouvez utiliser
_
:Le trait de soulignement,,
_
est l' identificateur vide , un espace réservé anonyme.la source
element
est la valeur de l'élément (une copie) - ce n'est pas l'élément lui-même. Bien que vous puissiez l'assigner àelement
, cela n'affectera pas la séquence sous-jacente._()
dans l'espace de noms local" ce qui est juste par convention , cela ne fait pas partie de la lib de localisation. Le trait de soulignement_
est une étiquette valide, et c'est également une convention dans Go (et Python et Scala et d'autres langs) à affecter aux_
valeurs de retour que vous n'utiliserez pas. La portée de_
dans cet exemple est limitée au corps de lafor
boucle. Si vous avez une fonction de portée de package,_
elle sera alors masquée dans la portée de la boucle for. Il y a quelques paquets pour la localisation, je n'ai vu aucune utilisation_
comme nom de fonction.Go a une
foreach
syntaxe similaire à. Il prend en charge les tableaux / tranches, les cartes et les canaux.Itérer sur un tableau ou une tranche :
Itérer sur une carte :
Itérer sur un canal :
Itérer sur un canal équivaut à recevoir d'un canal jusqu'à ce qu'il soit fermé:
la source
chan
utilisation: le fait de parcourir un canal quittera gracieusement la boucle si l'écrivain ferme le canal à un moment donné. Dans l'for {v := <-theChan}
équivalent , il ne sortira pas à la fermeture du canal. Vous pouvez le tester via la deuxièmeok
valeur de retour. EXEMPLE DE TOURfor { ... }
représente une boucle infinie.L'exemple suivant montre comment utiliser l'
range
opérateur dans unefor
boucle pour implémenter uneforeach
boucle.L'exemple parcourt un tableau de fonctions pour unifier la gestion des erreurs pour les fonctions. Un exemple complet est sur le terrain de jeu de Google .
PS: cela montre aussi que les accolades suspendues sont une mauvaise idée pour la lisibilité du code. Astuce: la
for
condition se termine juste avant l'action()
appel. Évident, non?la source
,
et il est plus clair où lafor
condition se termine: play.golang.org/p/pcRg6WdxBd - C'est en fait la première fois que je trouve un contre-argument augo fmt
style, merci!Vous pouvez en fait utiliser
range
sans référencer ses valeurs de retour en utilisantfor range
contre votre type:https://play.golang.org/p/XHrHLbJMEd
la source
Voici l'exemple de code pour savoir comment utiliser foreach dans golang
Ceci est un exemple en cours d'exécution https://play.golang.org/p/LXptmH4X_0
la source
Oui, plage :
La forme de plage de la boucle for itère sur une tranche ou une carte.
Lors d'une plage sur 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 :
la source
Cela peut être évident, mais vous pouvez aligner le tableau comme suit:
les sorties:
https://play.golang.org/p/gkKgF3y5nmt
la source