Qualidade de Código em Go: Opinativo por Design
Equipes Go raramente discutem sobre tabs vs. espaços.
Busque em todas as páginas da documentação
Equipes Go raramente discutem sobre tabs vs. espaços.
A linguagem e o toolchain vêm com padrões que codificam décadas de experiência de produção, deixando espaço para as equipes adicionarem portões mais rigorosos à medida que as bases de código amadurecem.
gofmt), correção estática (go vet) e testes como bases inegociáveis; todo o resto (staticcheck, gosec, analisadores personalizados) estende essa pilha.Os designers de Go escolheram consistência sem frescuras em vez de configurabilidade para estilo.
gofmt reescreve o código para um layout canônico.
Não há arquivo de estilo de projeto para discutir em revisão.
goimports estende a formatação adicionando, removendo e agrupando imports.
Juntos, eles respondem: "Este arquivo parece Go?"
go vet é a próxima camada.
Ele executa analisadores mantidos com a release do Go que sinalizam construções suspeitas: verbos de printf que não correspondem aos argumentos, código inalcançável, uso indevido de sync.Mutex, tags de struct que o JSON não consegue analisar, e mais.
Vet não é um verificador de estilo.
Ele visa erros que o compilador permite, mas que os humanos lamentam.
A terceira base é testes.
go test é o executor universal; -race adiciona um detector de race condition de dados; cobertura e benchmarks vivem na mesma ferramenta.
Cultura de qualidade em Go assume testes verdes antes do merge.
Equipes que precisam de maior alcance para o ecossistema de analisadores construído sobre go/analysis.
staticcheck encontra código morto e uso indevido de API.
gosec sinaliza padrões criptográficos arriscados e de injeção.
golangci-lint orquestra dezenas de linters com uma única configuração YAML.
A escada de maturidade típica:
Dia 1 gofmt + goimports (editor + verificação de diff na CI)
Semana 1 go vet ./... + go test ./...
Mês 1 golangci-lint preset + govulncheck na CI
Trimestre 1 Analisadores personalizados para APIs de domínio + rubrica de revisãoFerramentas de qualidade interagem em três velocidades: editor, hook local e CI.
gopls executa um subconjunto de analisadores enquanto você digita.
Hooks de pre-commit executam formatadores e verificações rápidas antes do git push.
A CI executa o pacote autoritativo em um checkout limpo com versões fixadas de Go e linters.
Verificações de formatação geralmente comparam a saída de gofmt -l com uma lista vazia ou usam gofmt -w em um job de correção.
A higiene de importação usa goimports -local example.com/mycorp para manter módulos internos agrupados separadamente de caminhos de terceiros.
Vet e golangci-lint compartilham DNA de analisador.
Muitas verificações de go vet aparecem dentro do golangci-lint como o linter govet.
Executar ambos é redundante, mas inofensivo; scripts frequentemente mantêm go vet para clareza em pipelines mínimos.
| Camada | Ferramenta | O que ela aplica | Modo de falha típico |
|---|---|---|---|
| Formato | gofmt, goimports | Layout e imports | CI falha em diff não formatado |
| Correção | go vet, staticcheck | APIs suspeitas, branches mortas | Diagnóstico do analisador |
| Segurança | gosec, govulncheck | Padrões arriscados, CVEs conhecidas | Bloqueia merge em alta severidade |
| Comportamento | go test, -race | Lógica e concorrência | Falha de teste ou race |
Monorepos adicionam configurações com escopo de caminho.
Um .golangci.yml raiz pode definir padrões; substituições por módulo desabilitam linters para protobuf gerado ou vendor/.
Workspaces go.work precisam de comandos de lint que respeitem o limite go.mod de cada módulo.
Adoção incremental é melhor que rigor "big-bang".
Comece com gofmt, go vet e testes.
Adicione golangci-lint com o preset standard ou fast.
Habilite staticcheck, errcheck e unused antes de linters de nicho.
Para código legado, use //nolint com referência de ticket ou regras de exclusão de linter para diretórios até que refatorações sejam aplicadas.
Código gerado (*.pb.go, mock_*.go) deve ser excluído de linters de estilo, mas ainda assim compilar e testar.
Política de biblioteca vs. serviço difere.
Módulos publicados enfrentam consumidores em versões mais antigas de Go; fixe a diretiva go e execute vet em todas as versões suportadas na matriz de CI.
Serviços internos podem avançar mais rapidamente em atualizações de toolchain.
Revisão humana ainda cobre arquitetura, gosto de nomenclatura e preocupações operacionais que linters não conseguem ver.
Codifique regras objetivas em analisadores; documente o julgamento subjetivo em Padrões de Revisão de Código para Equipes Go.
| Estratégia | Força | Fraqueza | Melhor ajuste |
|---|---|---|---|
| Mínima (gofmt + vet + test) | Onboarding rápido, baixo ruído | Perde segurança e bugs estáticos profundos | Ferramentas pequenas, startups iniciais |
| golangci-lint Padrão | Cobertura ampla, uma configuração | Tempo de ajuste, falsos positivos ocasionais | A maioria dos serviços de produção |
| Regras personalizadas de go/analysis | Garantias específicas de domínio | Custo de manutenção | Plataformas com SDKs públicos |
| Apenas formato em OSS | Baixo atrito para contribuidores | Qualidade mais profunda inconsistente | Bibliotecas open-source casuais |
//nolint; aumente o conjunto à medida que a base de código absorve cada regra.Um formato maximiza a legibilidade entre repos e minimiza discussões triviais.
Ferramentas e humanos reconhecem código Go instantaneamente.
gofmt -s também aplica simplificações (por exemplo, padrões de slice).
Muitas equipes executam gofmt simples; simplificações são opcionais, mas comuns em hooks.
goimports executa gofmt e gerencia blocos de importação.
Use goimports em editores; a CI pode verificar qualquer uma das ferramentas, desde que a equipe concorde.
Novos minors do Go frequentemente adicionam analisadores vet.
Trate as seções de ferramentas das notas de release como afetando a CI, não como leitura opcional.
Depois que gofmt, go vet e go test ./... estiverem verdes na CI.
Adicione quando a revisão capturar repetidamente os mesmos problemas da classe staticcheck.
Bibliotecas se beneficiam de verificações de API mais rigorosas (revive, ireturn).
Serviços adicionam linters de segurança e operacionais (gosec, bodyclose para HTTP).
Fixe a versão do golangci-lint na CI.
Documente a mesma versão para make lint local.
gopls fornece um sinal inicial, mas a CI permanece autoritativa.
Alguns linters assumem GOOS de desktop.
Escopo do lint para pacotes que compilam para cada alvo ou exclua tags de compilação tinygo na configuração.
Um make check documentado e um hook de pre-commit rápido integram mais rápido do que a tradição oral.
Padrões opinativos reduzem palestras sobre "como fazemos as coisas aqui".
Effective Go é orientação humana.
Automatize o que é objetivo (formato, vet, regras comuns do staticcheck); mantenha o restante em padrões de revisão.
Versões de Stack: Esta página foi escrita para Go 1.26.x (padrão Green Tea GC, modernizadores go fix - verifique o patch na compilação), chi (última versão - verifique na compilação), gin (última versão - verifique na compilação), echo (última versão - verifique na compilação), google.golang.org/grpc (última versão - verifique na compilação), sigs.k8s.io/controller-runtime (última versão - verifique na compilação), kubebuilder (última versão - verifique na compilação), tinygo (última versão - verifique os alvos de placa na compilação), wazero (última versão - verifique na compilação) e golangci-lint (última versão - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 16 de jul. de 2026