Existe uma foreach
construção no idioma Go? Posso iterar sobre uma fatia ou matriz usando a for
?
range
em for
laços também é mencionada na secção "um interlúdio sobre tipos de" seção (para o seu fim) do tutorial Go.
Existe uma foreach
construção no idioma Go? Posso iterar sobre uma fatia ou matriz usando a for
?
range
em for
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
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
}
O sublinhado,, _
é o identificador em branco , um espaço reservado anônimo.
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.
_()
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 for
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 :
// index and value
for i, v := range slice {}
// index only
for i := range slice {}
// value only
for _, v := range slice {}
Iterar sobre um mapa :
// key and value
for key, value := range theMap {}
// key only
for key := range theMap {}
// value only
for _, 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:
for {
v, ok := <-theChan
if !ok {
break
}
}
chan
uso: 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 ok
valor de retorno. EXEMPLO DE TOUR
for { ... }
significa um loop infinito.
O exemplo a seguir mostra como usar o range
operador em um for
loop para implementar um foreach
loop.
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;
}
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 da action()
chamada. Óbvio, não é?
,
e fique mais claro onde a for
condição termina: play.golang.org/p/pcRg6WdxBd - Essa é a primeira vez que encontrei um contra-argumento para o go fmt
estilo, obrigado!
De fato, você pode usar range
sem referenciar seus valores de retorno usando for range
contra 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++
}
A seguir está o código de exemplo de como usar o foreach no golang
package main
import (
"fmt"
)
func main() {
arrayOne := [3]string{"Apple", "Mango", "Banana"}
for index,element := range arrayOne{
fmt.Println(index)
fmt.Println(element)
}
}
Este é um exemplo em execução https://play.golang.org/p/LXptmH4X_0
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)
}
}
Isso pode ser óbvio, mas você pode incorporar a matriz da seguinte maneira:
package main
import (
"fmt"
)
func main() {
for _, element := range [3]string{"a", "b", "c"} {
fmt.Print(element)
}
}
saídas:
abc