Uma instrução "for" com uma cláusula "range" interage com todas as entradas de uma matriz, fatia, string ou mapa ou valores recebidos em um canal. Para cada entrada, atribui valores de iteração às variáveis de iteração correspondentes e, em seguida, executa o bloco.
Como um exemplo:
for index, element := range someSlice {// index is the index where we are// element is the element from someSlice for where we are}
Se você não se importa com o índice, pode usar _:
for _, element := range someSlice {// element is the element from someSlice for where we are}
Neste exemplo, elementé o valor do elemento (uma cópia) - não é o próprio elemento. Embora você possa atribuir a element, isso não afetará a sequência subjacente.
Nobar
Eu sei que em Python e C é frequente usar sublinhado como uma função para localização (ou seja, o gettext ). O uso de sublinhado causaria problemas no Go? O Go usa a mesma biblioteca para localização?
Sergiy Kolodyazhnyy
3
O @SergiyKolodyazhnyy Py docs diz que "a função (gettext) geralmente é apelidada como _()no espaço de nomes local", que é apenas por convenção , não faz parte da biblioteca de localização. O sublinhado _é um rótulo válido e também é uma convenção no Go (e Python e Scala e outros idiomas) para atribuir _valores retornados aos quais você não usará. O escopo _deste exemplo é restrito ao corpo do forloop. Se você tiver uma função com escopo definido no pacote _, ela estará sombreada no escopo do loop for. Existem alguns pacotes para localização, não vi nenhum uso _como nome de função.
Davos
150
Go tem uma foreachsintaxe parecida. Ele suporta matrizes / fatias, mapas e canais.
Iterar sobre matriz ou fatia :
// index and valuefor i, v := range slice {}// index onlyfor i := range slice {}// value onlyfor _, v := range slice {}
Iterar sobre um mapa :
// key and valuefor key,value:= range theMap {}// key onlyfor key := range theMap {}// value onlyfor _,value:= range theMap {}
Iterar sobre um canal :
for v := range theChan {}
A iteração sobre um canal é equivalente a receber de um canal até que ele seja fechado:
Embora o OP tenha solicitado apenas o uso de fatia, prefiro essa resposta, porque a maioria também precisará dos outros usos.
domoarigato 2/08/16
3
distinção importante sobre o chanuso: percorrer um canal sairá graciosamente do loop se o gravador fechar o canal em algum momento. No for {v := <-theChan}equivalente , ele não sai no canal fechado. Você pode testar isso através do segundo okvalor de retorno. EXEMPLO DE TOUR
colm.anseo 10/10
Pensou o mesmo ao lê-lo, for { ... }significa um loop infinito.
Levite
13
O exemplo a seguir mostra como usar o rangeoperador em um forloop para implementar um foreachloop.
O exemplo itera sobre uma matriz de funções para unificar o tratamento de erros para as funções. Um exemplo completo está no playground do Google .
PS: mostra também que suspensórios são uma má idéia para a legibilidade do código. Dica: a forcondição termina logo antes da action()chamada. Óbvio, não é?
Adicione um ,e fique mais claro onde a forcondição termina: play.golang.org/p/pcRg6WdxBd - Essa é a primeira vez que encontrei um contra-argumento para o go fmtestilo, obrigado!
Top742
@topskip ambos são válidos para fmt; apenas escolher o melhor :)
Filip Haglund
@FilipHaglund Não é o ponto se é válido. O ponto é que, na IMO, é mais claro onde a condição for termina nesse caso específico acima.
topskip
9
Na minha opinião, esta resposta é irracionalmente complexa para a pergunta direcionada.
precisa
@AndreasHassing Como fazer isso sem introduzir redundância?
ceving 16/01/19
10
De fato, você pode usar rangesem referenciar seus valores de retorno usando for rangecontra o seu 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++
}
Às vezes, é o exemplo mais simples que é o mais útil. Obrigado! Não tenho nada contra as respostas mais esotéricas dos outros comentaristas - eles certamente ilustram os meandros da programação Go muito idiomática, a ponto de se tornarem ... ilegíveis e difíceis de seguir - mas prefiro sua resposta: ela segue em frente até o núcleo com o exemplo mais simples possível (que funciona e é óbvio por que funciona).
Gwyneth Llewelyn
4
Sim, intervalo :
A forma de intervalo do loop for itera sobre uma fatia ou mapa.
Ao ultrapassar uma fatia, dois valores são retornados para cada iteração. O primeiro é o índice e o segundo é uma cópia do elemento nesse índice.
Exemplo:
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)}}
Você pode pular o índice ou valor atribuindo a _.
Se você deseja apenas o índice, solte o valor, inteiramente.
range
emfor
laços também é mencionada na secção "um interlúdio sobre tipos de" seção (para o seu fim) do tutorial Go.Respostas:
https://golang.org/ref/spec#For_range
Como um exemplo:
Se você não se importa com o índice, pode usar
_
:O sublinhado,,
_
é o identificador em branco , um espaço reservado anônimo.fonte
element
é o valor do elemento (uma cópia) - não é o próprio elemento. Embora você possa atribuir aelement
, isso não afetará a sequência subjacente._()
no espaço de nomes local", que é apenas por convenção , não faz parte da biblioteca de localização. O sublinhado_
é um rótulo válido e também é uma convenção no Go (e Python e Scala e outros idiomas) para atribuir_
valores retornados aos quais você não usará. O escopo_
deste exemplo é restrito ao corpo dofor
loop. Se você tiver uma função com escopo definido no pacote_
, ela estará sombreada no escopo do loop for. Existem alguns pacotes para localização, não vi nenhum uso_
como nome de função.Go tem uma
foreach
sintaxe parecida. Ele suporta matrizes / fatias, mapas e canais.Iterar sobre matriz ou fatia :
Iterar sobre um mapa :
Iterar sobre um canal :
A iteração sobre um canal é equivalente a receber de um canal até que ele seja fechado:
fonte
chan
uso: percorrer um canal sairá graciosamente do loop se o gravador fechar o canal em algum momento. Nofor {v := <-theChan}
equivalente , ele não sai no canal fechado. Você pode testar isso através do segundook
valor de retorno. EXEMPLO DE TOURfor { ... }
significa um loop infinito.O exemplo a seguir mostra como usar o
range
operador em umfor
loop para implementar umforeach
loop.O exemplo itera sobre uma matriz de funções para unificar o tratamento de erros para as funções. Um exemplo completo está no playground do Google .
PS: mostra também que suspensórios são uma má idéia para a legibilidade do código. Dica: a
for
condição termina logo antes daaction()
chamada. Óbvio, não é?fonte
,
e fique mais claro onde afor
condição termina: play.golang.org/p/pcRg6WdxBd - Essa é a primeira vez que encontrei um contra-argumento para ogo fmt
estilo, obrigado!De fato, você pode usar
range
sem referenciar seus valores de retorno usandofor range
contra o seu tipo:https://play.golang.org/p/XHrHLbJMEd
fonte
A seguir está o código de exemplo de como usar o foreach no golang
Este é um exemplo em execução https://play.golang.org/p/LXptmH4X_0
fonte
Sim, intervalo :
A forma de intervalo do loop for itera sobre uma fatia ou mapa.
Ao ultrapassar uma fatia, dois valores são retornados para cada iteração. O primeiro é o índice e o segundo é uma cópia do elemento nesse índice.
Exemplo:
fonte
Isso pode ser óbvio, mas você pode incorporar a matriz da seguinte maneira:
saídas:
https://play.golang.org/p/gkKgF3y5nmt
fonte