`defer`: ordem, avaliação de argumentos e o loop
Pergunta
Como `defer` funciona em Go em relação à ordem de execução e à avaliação dos argumentos, e qual a pegadinha de usar `defer` dentro de um loop?
Resposta esperada
`defer` agenda uma chamada pra rodar quando a FUNÇÃO retorna (não no fim do bloco), em ordem LIFO — o último `defer` roda primeiro. Os ARGUMENTOS da chamada deferida são avaliados NA HORA do `defer`, não na hora da execução: `defer fmt.Println(i)` captura o valor de `i` naquele momento (mas `defer func(){ fmt.Println(i) }()` captura a variável, então vê o valor final). Uso típico: `f, _ := os.Open(...); defer f.Close()` — cleanup junto da aquisição. Pegadinha do loop: `for _, path := range paths { f, _ := os.Open(path); defer f.Close() }` — os `Close` só rodam quando a função inteira retorna, então você abre milhares de arquivos e só fecha no fim (esgota file descriptors). Solução: extrair o corpo do loop numa função (o `defer` roda no fim dela), ou fechar explicitamente no loop.
Por que perguntam isso
Pergunta pleno de Go. A pegadinha do loop é o teste clássico. Sinal bom: 'argumento avaliado na hora do defer' vs closure capturando a variável.