Existe foreach em Go? Tutorial passo a passo com exemplos
\n\nSe você veio para Go a partir de Python, JavaScript ou PHP, provavelmente está acostumado com o conciso foreach para percorrer coleções. E então você escreve seu primeiro loop em Go e se pergunta: "Onde está meu amado foreach? Será que Go não tem isso?"
Spoiler: a palavra-chave direta foreach realmente não existe em Go. Mas existe algo muito mais flexível e poderoso — a construção for range. Neste tutorial, vamos analisar como a iteração funciona em Go, mostrar exemplos reais de código e comparar com o foreach familiar de outras linguagens.
Por que não há foreach em Go e para que serve o range?
\n\nGo é uma linguagem minimalista. Seus criadores evitaram intencionalmente a duplicação de construções sintáticas. Em vez de adicionar uma palavra-chave separada foreach, eles expandiram as capacidades do loop for existente. Assim surgiu o for range — uma ferramenta universal para percorrer arrays, slices, maps, strings e até mesmo channels.
Se você está procurando um análogo exato do foreach em Go, aqui está ele — for range.
Sintaxe do for range: explicação simplificada
\n\nA estrutura básica é assim:
\n\nfor index, value := range collection {\n // corpo do loop\n}\n\nOnde:
\n- \n
index— o índice do elemento (para arrays e slices) ou a chave (para maps). \n value— uma cópia do valor do elemento. \n collection— sua coleção (slice, array, map, string ou channel). \n
Um ponto importante: value é sempre uma cópia do elemento. Se você alterar value dentro do loop, o elemento original não será modificado. Para alterar os originais, é necessário acessar através do índice.
Exemplo 1: Percorrendo um slice — análogo do foreach em Go
\n\nVamos começar com o caso mais comum — percorrer elementos de um slice:
\n\npackage main\n\nimport "fmt"\n\nfunc main() {\n fruits := []string{"maçã", "banana", "cereja", "melão"}\n\n fmt.Println("Percorrendo slice (análogo do foreach):")\n for index, fruit := range fruits {\n fmt.Printf("Índice %d: %s\\n", index, fruit)\n }\n}\n\nSaída:
\nPercorrendo slice (análogo do foreach):\nÍndice 0: maçã\nÍndice 1: banana\nÍndice 2: cereja\nÍndice 3: melão\n\nSe você precisar apenas do índice (por exemplo, para modificar elementos), pode omitir o valor:
\n\nfor i := range fruits {\n fruits[i] = "fruta: " + fruits[i]\n}\n\nE se precisar apenas dos valores — use o sublinhado _:
for _, fruit := range fruits {\n fmt.Println(fruit)\n}\n\nExemplo 2: Percorrendo um map — foreach clássico
\n\nEm Go, não há maneira mais elegante de percorrer maps do que com for range:
package main\n\nimport "fmt"\n\nfunc main() {\n ages := map[string]int{\n "Ana": 25,\n "Bruno": 30,\n "Carlos": 35,\n }\n\n fmt.Println("Percorrendo map (foreach):")\n for name, age := range ages {\n fmt.Printf("%s: %d anos\\n", name, age)\n }\n}\n\nA ordem de iteração de um map em Go não é garantida. Se você precisar de uma ordem estável, colete as chaves em um slice e ordene-o.
\n\nExemplo 3: Percorrendo uma string — iteração caractere por caractere
\n\nAo contrário de muitas linguagens, o for range em Go itera sobre runas (caracteres unicode), e não sobre bytes:
package main\n\nimport "fmt"\n\nfunc main() {\n text := "Olá, Go!"\n\n fmt.Println("Percorrendo string por caracteres:")\n for i, r := range text {\n fmt.Printf("Posição %d: caractere '%c' (código %U)\\n", i, r, r)\n }\n}\n\nObserve: o índice i indica o byte inicial da runa, e não o número ordinal do caractere. Para strings com um byte