Trilhas
/
Go
Go
/
Programa
/
Iteração com range
It

Iteração com range em Go

1 exercício

Sobre Iteração com range

Em Go, for range repete um bloco de código para os valores de uma expressão de range. A expressão de range determina se cada iteração vai produzir um valor ou dois.

Expressões de range

Range sobre um slice

range sobre um slice produz o índice e o valor de cada elemento, em ordem:

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

Range sobre um map

range sobre um map produz cada chave e cada valor, mas a ordem da iteração não é garantida. Go embaralha de propósito a ordem de iteração dos maps, então o mesmo programa pode produzir uma saída diferente a cada execução.

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 uma string

range sobre uma string produz o índice em bytes e cada rune (ponto de código Unicode). No exemplo a seguir, 子 ocupa três bytes, então 猫 começa no índice de byte 3, e não em 1.

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

Se você precisar de índices de runes, converta a string em um slice de runes:

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

Range sobre um número inteiro

range pode iterar diretamente sobre um número inteiro, produzindo valores de 0 até, mas sem incluir, esse número inteiro. O valor zero e os valores negativos são válidos, mas não geram nenhuma iteração.

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

Range sobre um iterador

range aceita um iterador do tipo iter.Seq[V] ou iter.Seq2[K, V]. Um iterador é uma função que produz uma sequência de valores, um de cada vez. O range pode então percorrer esses 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 um canal

Por fim, o range pode receber valores enviados por um canal até que esse canal seja fechado em outro lugar. Os canais são abordados com mais profundidade mais adiante no programa da trilha.

Omitindo o índice ou o valor

Go não compila se uma variável for declarada e nunca usada.

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

Se você só precisar do valor, atribua o índice ou a chave a _ para ignorá-lo.

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

Se você só precisar do índice, omita o valor por completo:

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

Se você não precisar nem do índice nem do valor, os dois podem ser omitidos:

vals := []int{10, 20, 30}
count := 0
for range vals {
    count++
}
// count == 3
Editar via GitHub O link abre em uma nova janela ou aba

Aprenda Iteração com range