Um loop para todos os casos
A maioria das linguagens de programação oferece vários construtos de loop: for, while e do-while cada um serve a um propósito ligeiramente diferente — iterar um número fixo de vezes, executar até que uma condição mude, ou executar pelo menos uma vez antes de verificar. Go fez uma simplificação deliberada: tem apenas a keyword for, e ela cobre todos esses casos de uso dependendo de como você a escreve.
Há três formas:
- For com condição — equivalente a um loop
while - For com for clause — a forma clássica
init; condition; post - For com range clause — iteração sobre coleções
For com condição
Esta é a forma mais simples. O loop continua executando enquanto a condição for true, e para assim que ela se tornar false:
Este é o equivalente Go de um loop while em outras linguagens. Se você tem uma condição que quer verificar antes de cada iteração — sem nenhum init ou post statement — essa é a forma certa.
Loop infinito
Se você omitir a condição completamente, ela assume true por padrão e o loop executa para sempre. Esta é a forma idiomática de escrever um loop infinito em Go:
Loops infinitos são usados em servers, event loops e background workers que devem rodar até o programa encerrar ou um break explícito ser alcançado.
For com for clause
Esta é a forma clássica estilo C com três componentes separados por ponto e vírgula:
As três partes são:
| Parte | Função | No exemplo |
|---|---|---|
| Init statement | Executa uma vez antes do loop começar | i := 0 |
| Condition | Verificada antes de cada iteração; loop para quando falsa | i < 5 |
| Post statement | Executa após cada corpo de iteração | i++ |
Qualquer uma das três partes pode ser omitida. Omitir a condição torna o loop infinito (igual a for { }). Omitir o init ou o post deixa apenas um placeholder de ponto e vírgula:
For com range clause
A forma range itera sobre elementos de uma coleção. Funciona com arrays, slices, strings, maps e channels. O número de variáveis de iteração que ela fornece depende do que você está iterando.
Arrays e slices
range em um array ou slice fornece o index e o valor em cada posição:
Se você só precisa do index, omita a segunda variável. Se só precisa do valor, descarte o index com _:
Strings
range em uma string itera sobre code points Unicode (runes), não bytes. A primeira variável é o byte offset onde o rune começa, e a segunda é o valor do rune em si:
Esta é a forma idiomática de iterar sobre caracteres em uma string. Como abordado no artigo sobre strings, a indexação direta de bytes em caracteres multi-byte produz valores brutos de bytes, não os caracteres esperados.
Maps
range em um map fornece a key e o value para cada entrada:
Channels
range em um channel recebe valores um de cada vez até que o channel seja fechado:
Diferente de outras formas de range, iterar sobre um channel fornece apenas uma variável — o valor recebido. Não há index. O loop bloqueia aguardando o próximo valor e encerra de forma limpa quando o channel é fechado. Se o channel nunca for fechado, o loop executa para sempre.
break e continue
Tanto break quanto continue funcionam da mesma forma que em outras linguagens. break sai do loop imediatamente. continue pula o restante da iteração atual e passa para a próxima: