Clean Code em Go: princípios e exemplos para Golang
Código limpo (Clean Code) não é apenas um conjunto de regras, mas uma filosofia de desenvolvimento que torna o programa compreensível, fácil de manter e estender. Na linguagem Go, criada com foco em simplicidade e legibilidade, os princípios de código limpo são especialmente importantes. Neste artigo, vamos analisar os princípios-chave do Clean Code aplicados ao Go (Golang) e fornecer exemplos práticos que ajudarão você a escrever um código de maior qualidade.
1. Nomenclatura de variáveis, funções e pacotes
Em Go, a nomenclatura é a base da legibilidade. Bons nomes devem ser curtos, mas informativos. Evite abreviações que não sejam óbvias e não use variáveis de uma única letra (exceto para índices de loops).
Exemplo de código ruim:
package main
func f(x int) int { r := x * 2 return r}Exemplo de código limpo:
package main
// Double retorna o valor duplicado do número.func Double(value int) int { result := value * 2 return result}Regras de nomenclatura em Go:
- Variáveis: use camelCase (por exemplo,
userName,itemCount). Para variáveis globais — PascalCase, se forem exportadas. - Funções: funções exportadas começam com letra maiúscula, funções não exportadas começam com letra minúscula. O nome deve refletir a ação (por exemplo,
CalculateSum,parseInput). - Pacotes: nomes de pacotes devem ser curtos, em letras minúsculas e no singular (por exemplo,
fmt,http,strings). Evite nomes genéricos comoutils.
2. Tratamento de erros e retorno de valores
Go não usa exceções, mas retorna erros como valores. Código limpo exige verificação explícita de erros e evita panics no fluxo normal de execução.
Exemplo de código ruim:
func readFile(path string) string { data, _ := os.ReadFile(path) // Ignorando o erro return string(data)}Exemplo de código limpo:
func readFile(path string) (string, error) { data, err := os.ReadFile(path) if err != nil { return "", fmt.Errorf("erro ao ler arquivo %s: %w", path, err) } return string(data), nil}Recomendações para tratamento de erros:
- Sempre verifique os erros retornados. Não use
_para ignorá-los. - Encapsule erros com
fmt.Errorfe%wpara preservar o contexto. - Não use
panicpara erros comuns — isso é para situações excepcionais (por exemplo, erros de inicialização). - Crie tipos de erro personalizados se precisar transmitir informações adicionais.
3. Estrutura de funções e redução de complexidade
Funções em Go devem ser curtas e executar apenas uma tarefa. Siga o princípio da responsabilidade única (Single Responsibility Principle). Se uma função ficar muito longa, divida-a em várias funções auxiliares.
Exemplo de código ruim:
func processOrder(order Order) error { // 1. Validação if order.ID == 0 { return errors.New("ID de pedido inválido") } // 2. Cálculo de desconto discount := 0.0 if order.Amount > 100 { discount = 0.1 } // 3. Envio de email err := sendEmail(order.Email, "Pedido processado") if err != nil { return err } // 4. Salvamento no BD err = saveOrder(order) if err != nil { return err } return nil}Exemplo de código limpo:
func processOrder(order Order) error { if err := validateO