Clean Code em Go: princípios e exemplos na prática
Código limpo (Clean Code) não é apenas uma tendência, mas uma necessidade para qualquer desenvolvedor profissional. No mundo Go, onde simplicidade e legibilidade estão enraizadas na filosofia da linguagem, seguir os princípios do código limpo é especialmente importante. Neste artigo, vamos explorar os principais princípios do Clean Code em Go com exemplos práticos que ajudarão você a escrever código fácil de ler, manter e expandir.
1. Nomenclatura de variáveis e funções
Em Go, os nomes devem ser curtos, mas informativos. Quanto menor o escopo da variável, mais curto pode ser seu nome. Este é um dos princípios básicos do Clean Code em Go.
Exemplo ruim:
func f(a int, b int) int { var x int = a + b return x}Exemplo bom:
func Sum(a, b int) int { result := a + b return result}Observe: a função se chama Sum, não f. A variável result indica imediatamente seu propósito. Em Go, é comum usar camelCase para variáveis locais e PascalCase para entidades exportadas (públicas).
2. Funções pequenas e responsabilidade única
Cada função em Go deve fazer apenas uma coisa. Este é o princípio da responsabilidade única (Single Responsibility Principle). Se uma função executa várias tarefas — divida-a em funções menores.
Exemplo ruim — a função faz demais:
func ProcessUserData(user User) error { // Validação if user.Name == "" { return errors.New("empty name") } // Salvando no BD err := db.Save(user) if err != nil { return err } // Enviando email err = email.SendWelcome(user.Email) if err != nil { return err } return nil}Exemplo bom — separação de responsabilidades:
func ValidateUser(user User) error { if user.Name == "" { return errors.New("empty name") } return nil}
func SaveUser(user User) error { return db.Save(user)}
func SendWelcomeEmail(email string) error { return email.SendWelcome(email)}
func ProcessUserData(user User) error { if err := ValidateUser(user); err != nil { return err } if err := SaveUser(user); err != nil { return err } return SendWelcomeEmail(user.Email)}Esse código é fácil de testar, depurar e modificar. Cada função tem um propósito claro.
3. Tratamento de erros em Go
Em Go, erros são valores. Um dos principais princípios do Clean Code em Go é sempre verificar erros e não ignorá-los. Use o padrão "early return" para reduzir o aninhamento.
Exemplo ruim — ignorando o erro:
data, _ := ioutil.ReadFile("config.json")// usando data sem verificar o erroExemplo bom:
data, err := os.ReadFile("config.json")if err != nil { return fmt.Errorf("failed to read config: %w", err)}// trabalhando com dataUse fmt.Errorf com o marcador %w para encapsular erros. Isso permite preservar a cadeia de chamadas e facilita a depuração.
4. Evite aninhamento profundo
Aninhamento profundo torna o código ilegível. Em Go, é comum usar guard clauses (cláusulas de guarda) e retorno antecipado.
Exemplo ruim:
func GetUserRole(userID int) (string, error) { if userID > 0 { user, err := db.FindUser(userID) if err == nil { if user.IsActive { return user.Role, nil } else { return "", errors.New("user is inactive") } } else { return "", err }