“Enquanto” virou “para”, o while disfarçado
Cheguei ao Go vindo de um arsenal cheio de laços: while, do‑while, for‑in, for‑of, forEach. Quando vi o primeiro bloco de código Go, a única palavra‑chave de iteração era for. Meu instinto tentou procurar um while e, naturalmente, falhou.
A verdade, porém, é que o while ainda existe, só que camuflado como um for com uma única condição:
// equivalente a while caféQuente { for caféQuente { // tomar um gole… }
A condição fica entre parênteses (opcional) e o corpo segue normalmente. Essa abordagem elimina a necessidade de memorizar duas palavras diferentes para fazer essencialmente a mesma coisa. É como descobrir que a mesma máquina de espresso pode servir tanto um “ristretto” quanto um “lungo” apenas ajustando a quantidade de água: a interface é a mesma, o comportamento muda conforme o parâmetro.
O loop infinito mais simples do universo, for { … }
Depois de me acostumar com o while camuflado, encontrei o loop infinito mais elegante que já vi:
for { // aqui a gente nunca sai… a menos que haja um break }
Sem condição, sem inicialização, sem pós‑expressão, nada além da palavra‑chave for e das chaves. É o equivalente a dizer “continue tirando espresso enquanto houver energia elétrica”. Naturalmente, o break ou um return dentro do bloco são os únicos “interruptores” que impedem a máquina de trabalhar eternamente.
A simplicidade desse padrão me fez lembrar que, às vezes, menos realmente é mais, não preciso de três partes de controle quando a lógica inteira cabe em uma única linha de decisão.
A beleza (e a frustração) do range
A verdadeira magia do for aparece quando usamos range para percorrer coleções, slices, arrays, maps, strings. O range devolve dois valores por iteração: o índice (ou chave) e o valor. Essa dupla permite escrever loops extremamente concisos:
cafés := []string{"espresso", "latte", "cappuccino"} for i, nome := range cafés { fmt.Printf("%d: %s\n", i, nome) }
Mas, vindo de linguagens que permitem ignorar silenciosamente o índice, a primeira reação foi de frustração ao ter que lidar com o blank identifier (_) quando eu não precisava dele:
for _, nome := range cafés { fmt.Println(nome) // índice descartado }
Na época, parecia um “custo extra”, como se a máquina de espresso exigisse que eu sempre escolhesse a dose, mesmo quando eu só queria o líquido. Hoje, porém, vejo o _ como um lembrete de que o Go prefere ser explícito: você está conscientemente dizendo “não me interessa esse valor”. Essa clareza evita bugs sutis, como confundir o índice com o valor ao manipular slices mutáveis.
Percorrendo maps, o range devolve a chave e o valor associados:
precos := map[string]float64{ "espresso": 1.50, "latte": 2.30, } for bebida, preco := range precos { fmt.Printf("%s custa €%.2f\n", bebida, preco) }
Novamente, se eu quiser apenas as chaves ou apenas os valores, uso _ para descartar o que não preciso. Essa disciplina de “usar ou descartar explicitamente” reforça a filosofia do Go: menos ambiguidade, mais segurança.
Analogia da máquina de espresso
Imagine que você entra numa cafeteria minimalista onde há uma única máquina. Essa máquina tem três botões:
| Botão | Configuração | Resultado |
|---|---|---|
| Curto | for i := 0; i < n; i++ {} | Um número fixo de repetições (como um espresso rápido). |
| Longo | for condição {} | Repete enquanto a condição for verdadeira (como um lungo que continua enquanto houver água). |
| Infinito | for {} | Funciona até alguém apertar o botão de parada (break). |
Independentemente do botão que você aperta, a máquina permanece a mesma. Da mesma forma, o for em Go é a única estrutura de iteração, mas pode ser configurada de três maneiras distintas, curta, longa ou infinita, e ainda pode ser combinada com range para percorrer coleções. Essa uniformidade reduz a carga cognitiva: não preciso lembrar de quatro palavras‑chave diferentes, apenas de como ajustar os parâmetros da única ferramenta que tenho.
Conclusão (e próximo passo)
Neste deserto de loops, descobri que a aparente aridez esconde um oásis de simplicidade. O for cobre todos os casos que eu costumava espalhar entre while, do‑while, for‑in, for‑of e forEach. Ele faz isso com uma sintaxe enxuta, permitindo que eu foque na lógica do programa em vez de na variedade de palavras‑chave.
Pronto para seguir adiante? No próximo capítulo exploraremos o momento “Aha!”, como as goroutines e channels transformam a forma como pensamos concorrência, trazendo um novo tipo de “espresso duplo” ao nosso repertório.

Comentários