Code review em Go: o que verificar e como dar feedback
\nCode review (revisão de código) não é apenas uma verificação formal antes do merge de um pull request. É uma ferramenta poderosa para melhorar a qualidade do código, compartilhar conhecimento na equipe e prevenir erros nas fases iniciais. Para desenvolvedores Go iniciantes, participar de revisões pode parecer estressante: é assustador receber críticas ou, ao contrário, deixar passar um erro crítico. Neste artigo, vamos abordar o que observar ao revisar código Go e como dar feedback de forma útil, não ofensiva.
\n\nPor que o code review é importante especialmente em Go?
\nA linguagem Go foi criada com foco em simplicidade, legibilidade e confiabilidade. No entanto, a simplicidade da sintaxe não elimina a complexidade da lógica. Problemas típicos em projetos Go: ignorar erros, manipulação incorreta de goroutines, vazamentos de recursos. Um bom code review ajuda a identificar esses e outros problemas antes que cheguem à produção.
\n\nO que verificar no código Go: checklist para iniciantes
\nPara que a revisão seja sistemática, use um checklist. Aqui estão os principais pontos a verificar em cada pull request.
\n\n1. Tratamento de erros (error handling)
\nEm Go, erros são valores e não podem ser ignorados. Verifique se cada função que retorna error o trata ou o repassa explicitamente.
// Ruim: ignorando o erro\nfile, _ := os.Open("config.yaml")\n\n// Bom: tratando o erro\nfile, err := os.Open("config.yaml")\nif err != nil {\n log.Fatalf("não foi possível abrir config: %v", err)\n}\ndefer file.Close()\nVerifique também se os erros são encapsulados com fmt.Errorf("...: %w", err) para transmitir contexto, em vez de apenas serem registrados e ignorados.
2. Nomenclatura e legibilidade
\nEm Go, nomes curtos são usados para variáveis (por exemplo, r para reader, w para writer) e nomes longos para funções exportadas. Verifique se:
- \n
- Funções, tipos e variáveis exportadas têm comentários (começando com o nome da entidade). \n
- Os nomes das variáveis refletem sua finalidade (não
a,b,tmp). \n - Não há abreviações desnecessárias (
calcé melhor substituído porcalculate). \n
3. Trabalho com goroutines e concorrência
\nGoroutines são uma ferramenta poderosa, mas perigosa. Verifique:
\n- \n
- Se há um mecanismo de sincronização (canais, mutexes) para dados compartilhados. \n
- Se não estão sendo criadas goroutines "vazando" (goroutine leak). Use contexto (
context.Context) para cancelamento. \n - Se a goroutine não está bloqueada para sempre (deadlock). \n
// Exemplo de trabalho seguro com goroutine\nfunc worker(ctx context.Context, jobs <-chan int, results chan<- int) {\n for {\n select {\n case job, ok := <-jobs:\n if !ok {\n return\n }\n results <- job * 2\n case <-ctx.Done():\n return\n }\n }\n}\n\n4. Gerenciamento de recursos (defer)
\nVerifique se todos os arquivos abertos, conexões de rede, transações de banco de dados são fechados com defer. Isso deve ser feito imediatamente após a abertura bem-sucedida do recurso.
// Correto: fechando imediatamente\nconn, err := net.Dial("tcp", "example.com:80")\nif err != nil {\n return err\n}\ndefer conn.Close()\n\n5. Testes
\nIniciantes frequentemente esquecem os testes. Certifique-se de que testes unitários foram escritos para a nova lógica. Verifique:
\n- \n
- Os testes cobrem não apenas o caminho feliz (happy path), mas também casos limite. \n
- Se
t.Runestá sendo usado para subtestes. \n - Se não há testes que dependem de recursos externos (banco de dados, rede) sem mocks. \n
Como dar feedback: 5 regras para iniciantes
\nA parte técnica é metade do trabalho. A outra metade é a habilidade de se comunicar. Aqui est