Neste terceiro artigo da série “Golang para Iniciantes”, vamos explorar as estruturas de controle de fluxo em Go. Você aprenderá a tomar decisões com if/else, selecionar entre múltiplas opções com switch, e repetir operações com loops for.
Se você está chegando agora, recomendamos começar pela introdução:
📖 ← Artigo Anterior: Sintaxe Básica de Go
If e Else
Go tem uma sintaxe de condicionais limpa e direta.
If Básico
package main
import "fmt"
func main() {
idade := 18
if idade >= 18 {
fmt.Println("Maior de idade")
}
}
If-Else
package main
import "fmt"
func main() {
nota := 7.5
if nota >= 7.0 {
fmt.Println("Aprovado!")
} else if nota >= 5.0 {
fmt.Println("Recuperação")
} else {
fmt.Println("Reprovado")
}
}
If com Inicialização
Uma característica única de Go: você pode inicializar variáveis no if:
package main
import (
"fmt"
"math/rand"
"time"
)
func main() {
rand.Seed(time.Now().UnixNano())
// A variável 'numero' só existe dentro do bloco if
if numero := rand.Intn(100); numero % 2 == 0 {
fmt.Printf("%d é par\n", numero)
} else {
fmt.Printf("%d é ímpar\n", numero)
}
// numero não está acessível aqui!
}
Padrão Idiomático: Error Handling
O if com inicialização é muito usado para tratamento de erros:
package main
import (
"fmt"
"strconv"
)
func main() {
input := "42"
if numero, err := strconv.Atoi(input); err == nil {
fmt.Printf("Número: %d\n", numero)
} else {
fmt.Printf("Erro: %v\n", err)
}
}
Switch
O switch em Go é mais flexível que em outras linguagens.
Switch Básico
package main
import "fmt"
func main() {
dia := 3
switch dia {
case 1:
fmt.Println("Domingo")
case 2:
fmt.Println("Segunda")
case 3:
fmt.Println("Terça")
case 4:
fmt.Println("Quarta")
case 5:
fmt.Println("Quinta")
case 6:
fmt.Println("Sexta")
case 7:
fmt.Println("Sábado")
default:
fmt.Println("Dia inválido")
}
}
Nota: Em Go, você não precisa de
break— a execução não “cai” para o próximo case.
Múltiplos Cases
package main
import "fmt"
func main() {
mes := "janeiro"
switch mes {
case "dezembro", "janeiro", "fevereiro":
fmt.Println("Verão")
case "março", "abril", "maio":
fmt.Println("Outono")
case "junho", "julho", "agosto":
fmt.Println("Inverno")
case "setembro", "outubro", "novembro":
fmt.Println("Primavera")
}
}
Switch sem Expressão
Funciona como uma série de if-else:
package main
import "fmt"
func main() {
idade := 25
switch {
case idade < 13:
fmt.Println("Criança")
case idade < 20:
fmt.Println("Adolescente")
case idade < 60:
fmt.Println("Adulto")
default:
fmt.Println("Idoso")
}
}
Fallthrough
Se você realmente precisa que a execução continue para o próximo case:
package main
import "fmt"
func main() {
numero := 2
switch numero {
case 1:
fmt.Println("Um")
fallthrough
case 2:
fmt.Println("Dois")
fallthrough
case 3:
fmt.Println("Três")
}
// Output: Dois
// Três
}
Type Switch
Especialmente útil para trabalhar com interfaces:
package main
import "fmt"
func verificarTipo(i interface{}) {
switch v := i.(type) {
case int:
fmt.Printf("Inteiro: %d\n", v)
case string:
fmt.Printf("String: %s\n", v)
case bool:
fmt.Printf("Booleano: %t\n", v)
default:
fmt.Printf("Tipo desconhecido: %T\n", v)
}
}
func main() {
verificarTipo(42)
verificarTipo("Olá")
verificarTipo(true)
verificarTipo(3.14)
}
For: O Único Loop de Go
Go tem apenas uma palavra-chave para loops: for. Mas ela é extremamente versátil.
For Clássico (C-style)
package main
import "fmt"
func main() {
// Inicialização; condição; pós-operação
for i := 0; i < 5; i++ {
fmt.Printf("Iteração %d\n", i)
}
}
For como While
package main
import "fmt"
func main() {
contador := 0
// Apenas a condição
for contador < 5 {
fmt.Printf("Contador: %d\n", contador)
contador++
}
}
Loop Infinito
package main
import (
"fmt"
"time"
)
func main() {
contador := 0
// Loop infinito
for {
fmt.Printf("Execução %d\n", contador)
contador++
if contador >= 5 {
break // Sai do loop
}
time.Sleep(1 * time.Second)
}
}
Range
A forma idiomática de iterar sobre coleções:
package main
import "fmt"
func main() {
// Slice
frutas := []string{"maçã", "banana", "laranja"}
// Índice e valor
for i, fruta := range frutas {
fmt.Printf("%d: %s\n", i, fruta)
}
// Apenas valor (ignora índice com _)
for _, fruta := range frutas {
fmt.Println(fruta)
}
// Apenas índice
for i := range frutas {
fmt.Printf("Índice: %d\n", i)
}
}
Range com Map
package main
import "fmt"
func main() {
notas := map[string]float64{
"Alice": 9.5,
"Bob": 8.0,
"Carol": 9.0,
}
// Ordem de iteração em maps é aleatória!
for nome, nota := range notas {
fmt.Printf("%s: %.1f\n", nome, nota)
}
// Apenas chaves
for nome := range notas {
fmt.Println("Aluno:", nome)
}
}
Range com String
package main
import "fmt"
func main() {
texto := "Olá"
// Itera sobre runes (Unicode code points)
for i, runa := range texto {
fmt.Printf("Índice: %d, Rune: %c, Byte: %d\n", i, runa, runa)
}
}
Range com Canal
package main
import "fmt"
func main() {
numeros := make(chan int)
go func() {
for i := 0; i < 5; i++ {
numeros <- i
}
close(numeros)
}()
// Range sobre canal até ele ser fechado
for num := range numeros {
fmt.Println(num)
}
}
Controle de Execução
Break
Sai de um loop ou switch:
package main
import "fmt"
func main() {
for i := 0; i < 10; i++ {
if i == 5 {
break // Sai do loop quando i == 5
}
fmt.Println(i)
}
// Output: 0, 1, 2, 3, 4
}
Continue
Pula para a próxima iteração:
package main
import "fmt"
func main() {
for i := 0; i < 10; i++ {
if i%2 == 0 {
continue // Pula números pares
}
fmt.Println(i)
}
// Output: 1, 3, 5, 7, 9
}
Break com Labels
Sai de loops aninhados:
package main
import "fmt"
func main() {
externo:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if i == 1 && j == 1 {
break externo // Sai do loop externo
}
fmt.Printf("(%d, %d)\n", i, j)
}
}
// Output: (0, 0), (0, 1), (0, 2), (1, 0)
}
Goto
Evite usar goto, mas conheça sua existência:
package main
import "fmt"
func main() {
i := 0
loop:
if i >= 5 {
goto end
}
fmt.Println(i)
i++
goto loop
end:
fmt.Println("Fim")
}
Exercícios Práticos
Exercício 1: FizzBuzz
Implemente o clássico FizzBuzz: para números de 1 a 100, imprima “Fizz” se divisível por 3, “Buzz” se divisível por 5, “FizzBuzz” se divisível por ambos, ou o número caso contrário.
Ver solução
package main
import "fmt"
func main() {
for i := 1; i <= 100; i++ {
switch {
case i%15 == 0:
fmt.Println("FizzBuzz")
case i%3 == 0:
fmt.Println("Fizz")
case i%5 == 0:
fmt.Println("Buzz")
default:
fmt.Println(i)
}
}
}
Exercício 2: Tabuada
Crie um programa que imprima a tabuada de um número usando loops aninhados.
Ver solução
package main
import "fmt"
func main() {
// Tabuada de 1 a 10
for i := 1; i <= 10; i++ {
fmt.Printf("Tabuada do %d:\n", i)
for j := 1; j <= 10; j++ {
fmt.Printf(" %d x %d = %d\n", i, j, i*j)
}
fmt.Println()
}
}
Exercício 3: Busca em Slice
Implemente uma função que busca um elemento em um slice e retorna seu índice (ou -1 se não encontrado).
Ver solução
package main
import "fmt"
func buscar(slice []int, alvo int) int {
for i, v := range slice {
if v == alvo {
return i
}
}
return -1
}
func main() {
numeros := []int{10, 25, 30, 45, 50}
indice := buscar(numeros, 30)
if indice != -1 {
fmt.Printf("Encontrado no índice %d\n", indice)
} else {
fmt.Println("Não encontrado")
}
}
Exercício 4: Calculadora com Menu
Crie uma calculadora interativa com menu usando switch.
Ver solução
package main
import (
"fmt"
)
func main() {
var opcao int
var a, b float64
for {
fmt.Println("\n=== Calculadora ===")
fmt.Println("1. Soma")
fmt.Println("2. Subtração")
fmt.Println("3. Multiplicação")
fmt.Println("4. Divisão")
fmt.Println("0. Sair")
fmt.Print("Escolha: ")
fmt.Scan(&opcao)
if opcao == 0 {
fmt.Println("Até logo!")
break
}
fmt.Print("Digite o primeiro número: ")
fmt.Scan(&a)
fmt.Print("Digite o segundo número: ")
fmt.Scan(&b)
switch opcao {
case 1:
fmt.Printf("Resultado: %.2f\n", a+b)
case 2:
fmt.Printf("Resultado: %.2f\n", a-b)
case 3:
fmt.Printf("Resultado: %.2f\n", a*b)
case 4:
if b == 0 {
fmt.Println("Erro: divisão por zero")
} else {
fmt.Printf("Resultado: %.2f\n", a/b)
}
default:
fmt.Println("Opção inválida")
}
}
}
Padrões Comuns
Iteração com Índice
for i := 0; i < len(slice); i++ {
// Acesso por índice
}
Iteração com Range
for i, v := range slice {
// i = índice, v = valor
}
Loop Infinito com Condição de Saída
for {
// faz algo
if condicao {
break
}
}
Retry com Limite
for tentativa := 0; tentativa < maxTentativas; tentativa++ {
err := fazerAlgo()
if err == nil {
break // Sucesso
}
if tentativa == maxTentativas-1 {
return err // Última tentativa falhou
}
time.Sleep(time.Second * time.Duration(tentativa+1))
}
Dicas e Melhores Práticas
1. Prefira Range
Use range quando possível — é mais idiomático:
// Bom
for _, item := range lista {
processar(item)
}
// Evite (a menos que precise do índice)
for i := 0; i < len(lista); i++ {
processar(lista[i])
}
2. Cuidado com Maps e Range
A ordem de iteração em maps é aleatória:
// Se precisar de ordem, ordene as chaves primeiro
var chaves []string
for k := range mapa {
chaves = append(chaves, k)
}
sort.Strings(chaves)
for _, k := range chaves {
fmt.Println(k, mapa[k])
}
3. Evite Modificar o Slice Durante Iteração
// Perigoso: comportamento indefinido
for i := range slice {
if condicao(slice[i]) {
slice = append(slice[:i], slice[i+1:]...)
}
}
// Melhor: criar novo slice
var novoSlice []Tipo
for _, item := range slice {
if !condicao(item) {
novoSlice = append(novoSlice, item)
}
}
4. Use Defer em Loops com Cuidado
// Ruim: defer dentro de loop acumula chamadas
for _, arquivo := range arquivos {
f, _ := os.Open(arquivo)
defer f.Close() // Não fecha até a função retornar!
}
// Bom: função anônima
for _, arquivo := range arquivos {
func() {
f, _ := os.Open(arquivo)
defer f.Close()
// processa arquivo
}()
}
Próximos Passos
Excelente! Você agora domina o controle de fluxo em Go. Prepare-se para o próximo nível:
Próximo Artigo da Série
📖 Concorrência em Go: Goroutines e Channels → — A feature mais poderosa de Go: programação concorrente simplificada.
Desafios
- Ordenação: Implemente Bubble Sort ou Selection Sort
- Primos: Encontre todos os números primos até N
- Palíndromo: Verifique se uma string é palíndromo
- Fibonacci: Gere a sequência de Fibonacci
Recursos
Artigo anterior: Sintaxe Básica de Go ←
Próximo artigo: Concorrência em Go: Goroutines e Channels →
Última atualização: 09 de fevereiro de 2026
Versão do Go: 1.23