¿Hay una foreach
construcción en el lenguaje Go? ¿Puedo iterar sobre un segmento o matriz usando a for
?
range
in for
loops también se menciona en la sección "Un Interludio sobre Tipos" (hacia su final) del tutorial Go.
¿Hay una foreach
construcción en el lenguaje Go? ¿Puedo iterar sobre un segmento o matriz usando a for
?
range
in for
loops también se menciona en la sección "Un Interludio sobre Tipos" (hacia su final) del tutorial Go.
Respuestas:
https://golang.org/ref/spec#For_range
Una declaración "for" con una cláusula "range" itera a través de todas las entradas de una matriz, segmento, cadena o mapa, o valores recibidos en un canal. Para cada entrada, asigna valores de iteración a las variables de iteración correspondientes y luego ejecuta el bloque.
Como ejemplo:
for index, element := range someSlice {
// index is the index where we are
// element is the element from someSlice for where we are
}
Si no le importa el índice, puede usar _
:
for _, element := range someSlice {
// element is the element from someSlice for where we are
}
El guión bajo, _
es el identificador en blanco , un marcador de posición anónimo.
element
es el valor del elemento (una copia), no es el elemento en sí. Aunque puede asignar a element
, esto no afectará la secuencia subyacente.
_()
en el espacio de nombres local", que es solo por convención , no es parte de la biblioteca de localización. El guión bajo _
es una etiqueta válida, y también es una convención en Go (y Python y Scala y otros langs) para asignar _
valores de retorno que no usará. El alcance de _
en este ejemplo está restringido al cuerpo del for
bucle. Si tiene una función de ámbito de paquete _
, se sombreará dentro del alcance del bucle for. Hay algunos paquetes para la localización, no he visto ningún uso _
como nombre de función.
Go tiene una foreach
sintaxis similar. Es compatible con matrices / sectores, mapas y canales.
Iterar sobre matriz o corte :
// index and value
for i, v := range slice {}
// index only
for i := range slice {}
// value only
for _, v := range slice {}
Iterar sobre un mapa :
// key and value
for key, value := range theMap {}
// key only
for key := range theMap {}
// value only
for _, value := range theMap {}
Iterar sobre un canal :
for v := range theChan {}
Iterar sobre un canal es equivalente a recibir desde un canal hasta que se cierra:
for {
v, ok := <-theChan
if !ok {
break
}
}
chan
uso: si se extiende sobre un canal, saldrá del ciclo con gracia si el escritor cierra el canal en algún momento. En el for {v := <-theChan}
equivalente , será no salir en el canal cerca. Puede probar esto a través del segundo ok
valor de retorno. EJEMPLO
for { ... }
significa un bucle infinito.
El siguiente ejemplo muestra cómo usar el range
operador en un for
bucle para implementar un foreach
bucle.
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;
}
El ejemplo itera sobre una matriz de funciones para unificar el manejo de errores para las funciones. Un ejemplo completo es en el patio de juegos de Google .
PD: muestra también que los brackets colgantes son una mala idea para la legibilidad del código. Sugerencia: la for
condición termina justo antes de la action()
llamada. Obvio, ¿no es así?
,
está más claro dónde for
termina la condición: play.golang.org/p/pcRg6WdxBd : esta es la primera vez que encuentro un argumento contrario al go fmt
estilo, ¡gracias!
De hecho, puede usar range
sin hacer referencia a sus valores de retorno al usar for range
contra su 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++
}
El siguiente es el código de ejemplo de cómo usar foreach en 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 es un ejemplo en ejecución https://play.golang.org/p/LXptmH4X_0
Sí, rango :
La forma de rango del bucle for itera sobre un segmento o mapa.
Cuando se extiende sobre un segmento, se devuelven dos valores para cada iteración. El primero es el índice, y el segundo es una copia del elemento en ese índice.
Ejemplo:
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)
}
}
Esto puede ser obvio, pero puede alinear la matriz así:
package main
import (
"fmt"
)
func main() {
for _, element := range [3]string{"a", "b", "c"} {
fmt.Print(element)
}
}
salidas:
abc