Tracks
/
Go
Go
/
Temario
/
Iteración con range
It

Iteración con range en Go

1 ejercicio

Acerca de Iteración con range

En Go, for range repite un bloque de código para los valores de una expresión de rango. La expresión de rango determina si cada iteración producirá uno o dos valores.

Expresiones de rango

Range sobre un slice

range sobre un slice produce el índice y el valor de cada elemento en orden:

vals := []int{10, 20, 30}
for i, v := range vals {
    fmt.Println(i, v)
}
// 0 10
// 1 20
// 2 30

Range sobre un map

range sobre un map produce cada clave y valor, pero el orden de iteración no está garantizado. Go aleatoriza deliberadamente el orden de iteración de los map, así que un mismo programa puede producir una salida distinta en cada ejecución.

hash := map[int]int{9: 10, 99: 20, 999: 30}
for k, v := range hash {
    fmt.Println(k, v)
}
// 99 20
// 999 30
// 9 10

Range sobre un string

range sobre un string produce el índice de byte y cada rune (punto de código Unicode). En el siguiente ejemplo, 子 ocupa tres bytes, así que 猫 empieza en el índice de byte 3, no en el 1.

for i, r := range "子猫" {
    fmt.Println(i, r, string(r))
}
// 0 23376 子
// 3 29483 猫

Si en su lugar necesitas índices de runes, convierte el string en un slice de runes:

for i, r := range []rune("子猫") {
    fmt.Println(i, r, string(r))
}
// 0 23376 子
// 1 29483 猫

Range sobre un número entero

range puede iterar directamente sobre un número entero, produciendo valores desde 0 hasta ese número entero, sin incluirlo. El cero y los valores negativos son válidos, pero no producen ninguna iteración.

for n := range 3 {
    fmt.Println(n)
}
// 0
// 1
// 2

Range sobre un iterador

range acepta un iterador de tipo iter.Seq[V] o iter.Seq2[K, V]. Un iterador es una función que produce una secuencia de valores de uno en uno. Después, range puede recorrer esos valores.

text := "The quick brown fox"
for word := range strings.FieldsSeq(text) {
    fmt.Println(word)
}
// The
// quick
// brown
// fox

names := []string{"Alice", "Bob", "Vera"}
for i, v := range slices.All(names) {
    fmt.Println(i, ":", v)
}
// 0 : Alice
// 1 : Bob
// 2 : Vera

Range sobre un canal

Por último, range puede recibir valores enviados a través de un canal hasta que ese canal se cierre en otro lugar. Los canales se explican con más detalle más adelante en el temario del track.

Omitir el índice o el valor

Go no compilará si se declara una variable y no se usa nunca.

vals := []int{10, 20, 30}
for i, v := range vals {
    fmt.Println(v)
}
// Go build failed: declared and not used: i

Si solo necesitas el valor, asigna el índice o la clave a _ para ignorarlo.

vals := []int{10, 20, 30}
for _, v := range vals {
    fmt.Println(v)
}
// 10
// 20
// 30

Si solo necesitas el índice, omítelo por completo:

vals := []int{10, 20, 30}
for i := range vals {
    fmt.Println(i)
}
// 0
// 1
// 2

Si no necesitas ni el índice ni el valor, puedes omitir ambos:

vals := []int{10, 20, 30}
count := 0
for range vals {
    count++
}
// count == 3
Editar en GitHub El enlace se abre en una nueva ventana o pestaña

Aprende Iteración con range