Habilidade de Mestria em Go
Escreva Go idiomático e de nível de produção para qualquer finalidade. Esta habilidade codifica a sabedoria coletiva do ecossistema Go a partir do Go 1.22+ (2024–2026).
Versão base do Go: 1.22 | Funcionalidades até: 1.26 | Atualizado: Fevereiro de 2026
Antes de escrever qualquer código Go, internalize os princípios abaixo. Para aprofundamentos em tópicos específicos, leia os arquivos referenciados.
Arquivos de Referência — Leia Conforme Necessário
| Arquivo | Quando Ler |
|---|---|
references/concurrency.md | Qualquer goroutine, canal, primitiva de sincronização ou trabalho paralelo |
references/http-and-apis.md | Servidores HTTP, roteadores, middlewares, APIs REST/gRPC, WebSockets |
references/database.md | SQL, ORMs, pools de conexão, migrações, transações |
references/testing.md | Testes unitários, testes de integração, benchmarks, fuzzing |
references/errors-and-resilience.md | Tratamento de erros, retentativas, circuit breakers, degradação graciosa |
references/performance.md | Profiling, redução de alocações, ajuste de GC, benchmarking |
references/cli-and-config.md | Frameworks CLI, configuração, gerenciamento de ambiente |
references/project-patterns.md | Layout de projeto, DI, sistemas de plugins, geração de código |
references/platform-and-build.md | Compilação cruzada, especificidades do Windows, empacotamento, distribuição |
references/security.md | Autenticação, segredos, validação de entrada, TLS, padrões OWASP |
references/modern-go.md | Funcionalidades do Go 1.21–1.26, padrões obsoletos, o que o pré-treinamento erra |
references/advanced-patterns.md | Genéricos, máquinas de estado, streaming, agendamento, integração com IA/LLM |
references/advanced-resources.md | Recursos externos selecionados: internals do compilador/runtime, assembly, unsafe, cgo, Raft, operadores K8s, Wasm, criptografia, profiling, livros, conferências, artigos acadêmicos |
references/observability.md | Configuração do OpenTelemetry, tracing, métricas, logging estruturado com correlação de trace, health checks, flight recorder, checklist de instrumentação de produção |
references/ecosystem-and-tooling.md | Listas selecionadas (awesome-go), comparações de frameworks (web, ORM, CLI, DI, config), guias de estilo, CI/CD, Docker, gerenciamento de release, varredura de vulnerabilidades, plataformas de aprendizado, governança do Go |
references/internals.md | Escalonador GMP, garbage collector, modelo de memória, gerenciamento de pilha, alocador de memória, pipeline do compilador, unsafe, reflexão, diretivas do compilador |
references/networking.md | Servidores TCP/UDP, deadlines net.Conn, pool de conexões, mTLS, sockets Unix, resolvedores DNS, protocolos binários personalizados, gnet |
references/mcp-and-agents.md | Servidores MCP (mcp-go, SDK oficial), ferramentas/recursos/prompts, frameworks de agentes (ADK, langchaingo, eino), padrões multiagente, gopls MCP |
references/api-design.md | Nomenclatura REST, paginação (cursor/offset), erros RFC 9457, rate limiting, versionamento de API, codegen OpenAPI (oapi-codegen), compatibilidade reversa, cabeçalhos de depreciação |
references/cgo-and-interop.md | Básico de CGo, mapeamento de tipos C, gerenciamento de memória entre fronteiras, regras de passagem de ponteiros, callbacks, linkedição estática/dinâmica, compilação cruzada, alternativas puras em Go |
references/design-patterns.md | Padrões GoF em Go (factory, builder, strategy, observer, decorator), composição sobre herança, árvore de decisão |
references/distributed-systems.md | Raft, padrão outbox, sagas, locking distribuído, idempotência, CRDTs, hashing consistente |
references/cloud-native.md | Kubernetes client-go, operadores controller-runtime, admission webhooks, eleição de líder, Helm/Kustomize |
references/debugging-and-diagnostics.md | Depurador Delve, stack traces, flags GODEBUG, fluxo de trabalho de profiling, tabelas de sintoma-para-diagnóstico |
references/style-synthesis.md | Regras de estilo mescladas do Google + Uber + comunidade, nomenclatura, formatação, organização de código |
references/modules-and-dependencies.md | Operações go.mod, MVS, workspaces, GOPROXY, GOAUTH, vendoring, monorepos multi-módulo |
references/encoding-and-serialization.md | JSON (v1/v2), Protocol Buffers, MessagePack, CBOR, CSV, YAML, TOML, tabela de decisão de formato |
references/wasm-and-embedded.md | WebAssembly (WASI, navegador), go:wasmexport, TinyGo, padrões embarcados/IoT |
references/migration-guides.md | Traduções Go idiomáticas de Python, Java, TypeScript, Rust, C++ — mapas de conceitos e armadilhas |
references/testing-advanced.md | Testes baseados em propriedades (rapid), testes de contrato (Pact), testes de carga (Vegeta), engenharia do caos, synctest avançado |
references/supply-chain-security.md | govulncheck, geração de SBOM, framework SLSA, cosign, builds reproduzíveis, compatibilidade GODEBUG |
references/ebpf.md | eBPF a partir do Go (cilium/ebpf), fluxo de trabalho bpf2go, tracing, rede, profiling em nível de kernel |
references/event-driven.md | Consumidores/produtores Kafka, RabbitMQ, NATS, framework Watermill, DLQ, padrões exactly-once |
references/data-structures-and-caching.md | container/heap, container/list, caches LRU, singleflight, mapas fragmentados, filtros bloom, caches de referência fraca, padrões de estratégia de cache (aside/write-through/write-behind) |
references/ai-ml-beyond-llm.md | Inferência ONNX Runtime, Gonum, clientes de banco de dados vetoriais, pipelines de embedding, serving de ML a partir do Go |
references/file-io.md | Operações de arquivo, composição io.Reader/Writer, I/O bufferizado, streaming, manipulação de caminhos, os.Root, abstração fs.FS, fsnotify |
Filosofia Central
Go é deliberadamente simples. Resista ao impulso de importar complexidade de outros ecossistemas.
- Clareza sobre esperteza. O código é lido 10x mais do que escrito. Explícito vence implícito — mantenedores futuros (incluindo seu eu futuro) agradecerão.
- Composição sobre herança. Incorpore interfaces e structs; evite hierarquias profundas. Go não tem classes, e isso é intencional — peças pequenas e compostas vencem árvores de tipos complexas.
- Aceite interfaces, retorne structs. Funções devem depender de comportamento (interfaces) e expor tipos concretos. Isso mantém os pontos de chamada flexíveis enquanto mantém as implementações descobríveis e depuráveis.
- Torne o valor zero útil. Projete tipos de modo que
var x Testeja pronto para uso sem inicialização. Isso elimina toda uma classe de bugs de ponteiro nulo e torna as APIs naturais (bytes.Buffer,sync.Mutex,http.Clientfuncionam no valor zero). - Erros são valores. Trate-os; nunca os ignore. Empacote com contexto usando
fmt.Errorf("fazendo X: %w", err). Erros descartados tornam-se falhas silenciosas que aparecem horas depois em produção. - Não inicie goroutines que você não pode parar. Toda goroutine precisa de um caminho de desligamento via cancelamento de contexto ou fechamento de canal. Goroutines vazadas consomem memória indefinidamente e tornam o desligamento gracioso impossível.
- stdlib primeiro. A biblioteca padrão do Go é incomumente completa. Recorra a bibliotecas de terceiros apenas quando a stdlib genuinamente ficar aquém — menos dependências significam menos auditorias de segurança, menos conflitos de versão e builds mais rápidos.
- O código não está pronto até que esteja limpo no
gofmt, compile e passe novet. Executegofmt/goimports,go build,go vet,go test -raceegolangci-lint— torne-os portões de CI; o detector de corrida encontra bugs invisíveis na revisão. Ao emitir código sem acesso à ferramenta, mantenha o mesmo padrão manualmente: mantenha-o formatado como gofmt e inclua apenas as importações que você realmente usa (uma importação não utilizada é um erro de compilação — o deslize clássico logo após trocar um idioma por outro). - Honre o contrato do chamador, depois otimize. Quando uma tarefa especifica identificadores, assinaturas, formato de saída ou tipos exatos, reproduza-os exatamente — mesmo que você os nomeasse ou estruturasse de forma diferente. Padrão para a solução correta mais simples que satisfaça a especificação; adicione abstração, indireção ou camadas defensivas apenas quando a complexidade da tarefa exigir. Corresponder à superfície requerida é parte da correção — renomear ou reestruturar gratuitamente quebra chamadores e testes.
Estrutura do Projeto
Comece simples. Adicione estrutura apenas conforme o projeto exigir.
Binário Único (CLI ou serviço pequeno)
myapp/
├── go.mod
├── main.go # package main, ponto de entrada
├── app.go # lógica central da aplicação
├── app_test.go
└── internal/ # pacotes privados conforme necessário
└── parser/
├── parser.go
└── parser_test.go
Múltiplos Binários / Serviço de Produção
myproject/
├── go.mod
├── cmd/ # pontos de entrada — funções main() enxutas
│ ├── api-server/
│ │ └── main.go
│ └── worker/
│ └── main.go
├── internal/ # código de aplicação privado (imposto pelo compilador)
│ ├── auth/
│ ├── user/ # pacote de domínio: handler + service + repo
│ │ ├── handler.go
│ │ ├── service.go
│ │ ├── repository.go
│ │ └── model.go
│ ├── platform/ # transversal: db, cache, logging
│ │ ├── postgres/
│ │ └── redis/
│ └── middleware/
├── pkg/ # OPCIONAL: bibliotecas públicas reutilizáveis
├── api/ # Especificações OpenAPI, definições protobuf
├── migrations/ # Arquivos de migração SQL
├── scripts/ # Ferramentas de build, deploy, dev
├── configs/ # Arquivos de configuração padrão
└── Makefile
Regras principais:
internal/é imposto pelo compilador Go — o código aqui não pode ser importado por módulos externos.cmd/*/main.godeve ser enxuto: analisar flags, conectar dependências, chamarrun(), lidar com desligamento.- Agrupe por domínio/feature, não por camada técnica. Evite
models/,controllers/,services/— isso é estratificação no estilo Java que luta contra o modelo de pacotes do Go. - Evite pacotes
utils/,helpers/,common/— nomeie pacotes pelo que eles fornecem, pois nomes vagos atraem código não relacionado e tornam as importações sem sentido. - Um diretório É um pacote. Não crie diretórios apenas por organização.
Convenções de Nomenclatura
// Pacotes: curtos, minúsculos, palavra única. Sem sublinhados ou mixedCaps.
package user // bom
package userService // ruim — mixedCaps
// Exportados: MixedCaps. Não exportados: mixedCaps. Sublinhados são legais, mas a
// comunidade os trata como um bug de estilo — eles sinalizam código não idiomático.
func ParseRequest() // exportado
func parseHeader() // não exportado
// Interfaces: sufixo método + "-er" para interfaces de método único
type Reader interface { Read(p []byte) (n int, err error) }
type Validator interface { Validate() error }
// Getters: Owner(), não GetOwner(). Setters: SetOwner().
func (u *User) Name() string // getter — o prefixo "Get" não é Go
func (u *User) SetName(n string) // setter
// Acrônimos: tudo maiúsculo. URL, HTTP, ID, API — não Url, Http, Id, Api.
type HTTPClient struct{}
var userID int
// Variáveis de erro: ErrXxx. Tipos de erro: XxxError.
var ErrNotFound = errors.New("não encontrado")
type ValidationError struct { Field string; Message string }
// Contexto: primeiro parâmetro, sempre nomeado ctx. Esta é uma convenção Go universal
// que torna a propagação de contexto instantaneamente reconhecível em qualquer base de código.
func (s *Service) GetUser(ctx context.Context, id string) (*User, error)
Tratamento de Erros
Este é o padrão mais distinto do Go. Domine-o.
// Verifique cada erro — empacote com contexto usando %w
f, err := os.Open(name)
if err != nil {
return fmt.Errorf("abrindo config %s: %w", name, err)
}
defer f.Close()
// errors.AsType — extração de erro tipada genérica [Go 1.26+]
// Preferido em relação a errors.As: type-safe, sem necessidade de variável pré-declarada.
if pathErr, ok := errors.AsType[*fs.PathError](err); ok {
fmt.Println("falhou no caminho:", pathErr.Path)
}
Regras principais:
return errsem contexto torna a depuração dolorosa — sempre empacote comfmt.Errorf("fazendo X: %w", err).log.Fatal(err)em código de biblioteca chamaos.Exit(1), pulando a limpeza adiada — retorne erros para os chamadores.panic()é para bugs de programador, não para condições de runtime — retorne erros em vez disso.- Empacote erros de terceiros com
%v(não%w) para evitar acoplar chamadores ao tipo de erro subjacente. - Estilo de mensagem de erro: minúsculas, sem pontuação:
fmt.Errorf("lendo arquivo de configuração: %w", err).
Consulte references/errors-and-resilience.md para erros sentinela, tipos de erro personalizados, errors.Join, padrões de retentativa, circuit breakers e degradação graciosa.
Fundamentos de Concorrência
Consulte references/concurrency.md para padrões abrangentes, incluindo errgroup, pools de trabalhadores e fan-out/fan-in. Regras principais:
- Use context para cancelamento. Toda goroutine deve verificar
ctx.Done()— sem isso, não há como sinalizar "pare o trabalho." - Prefira
errgroupem vez desync.WaitGroupbruto. Agrupa espera + coleta de erros + cancelamento de contexto. Vejaconcurrency.mdpara exemplos completos comSetLimit. - Proteja o estado compartilhado — canais para comunicação, mutex quando mais simples. Comente o que cada mutex protege.
- Toda goroutine precisa de um caminho de desligamento. Sem verificação de cancelamento = goroutine vazada = vazamento de memória.
- Um pânico em uma goroutine mata todo o processo. Recupere-se em goroutines geradas, ou use
sourcegraph/conc.
Primitivas de sincronização novas:
sync.OnceValue / sync.OnceValues [Go 1.21+] — inicialização preguiçosa type-safe substituindo sync.Once + var de pacote:
var loadConfig = sync.OnceValues(func() ([]byte, error) {
return os.ReadFile("config.json") // executa exatamente uma vez, seguro de qualquer goroutine
})
data, err := loadConfig() // chamadas subsequentes retornam resultado em cache
sync.WaitGroup.Go [Go 1.25+] — combina Add(1) + go func + Done():
var wg sync.WaitGroup
wg.Go(func() { process(1) })
wg.Go(func() { process(2) })
wg.Wait()
Dimensionamento de canais: não bufferizados (0) para sincronização, bufferizados (1) para sinais, bufferizados (N) para trabalho com limite conhecido.
Interfaces
// Aceite interfaces, retorne tipos concretos
type UserStore interface {
GetUser(ctx context.Context, id string) (*User, error)
}
func NewService(store UserStore) *Service { return &Service{store: store} }
// Mantenha as interfaces pequenas — 1-3 métodos. Componha as maiores a partir de pequenas.
type ReadWriter interface { Reader; Writer }
// Defina a interface perto do consumidor, não do implementador.
// A interface pertence a quem a usa.
Ponteiros e Valores
- Ponteiros sinalizam mutabilidade ou nilabilidade. Use valores por padrão.
- Retorne
(*T, error)apenas quando nil for um resultado válido. Caso contrário, prefira(T, error). - Concorrência: passar um ponteiro para uma goroutine é assustador. Clone ao enviar por canal.
- Construtores:
NewXxxretorna*Xxx. Isso não é negociável em toda a comunidade.
Gerenciamento de Dependências
go mod init example.com/project
go get example.com/[email protected]
go mod tidy # adiciona/remove entradas go.sum
go mod verify # verifica a integridade das dependências
Uso mínimo: nenhuma importação fantasma, nenhum replace não explicado. Versões de pico diretas quando possível
Padrões de Teste
// Os testes pertencem ao mesmo pacote ou a um _test externo.
// Teste funcional, não estrutura interna.
func TestUserRepository(t *testing.T) {
t.Parallel()
// Arrange
db := setupTestDB(t)
repo := NewRepository(db)
// Act
user, err := repo.GetUser(context.Background(), "1")
// Assert
assert.NoError(t, err)
assert.Equal(t, "Alice", user.Name)
}
Regras de teste:
- Use
t.Parallel()sempre que possível para acelerar os testes. - Tabel driven tests para múltiplos cenários.
- Testes de integração:
//go:build integration. - Mínimos de cobertura: 80% para pacotes públicos, 100% para lógica de negócios.
- Mock apenas fronteiras externas: APIs HTTP, bancos de dados, sistemas de arquivos. Para mock, use
testify/mockougomock.
Veja references/testing.md para detalhes completos.
Próximos Passos
Para aplicar esta habilidade:
- Internalize os princípios acima.
- Consulte os arquivos de referência conforme necessário durante uma tarefa.
- Execute
gofmt,go vet,golangci-lintno código gerado. - Aderir às melhores práticas da comunidade Go.
Bom código, ótimo Go!