Pacotes e o sistema de módulos com go mod
1. Fundamentos de Pacotes em Go
Em Go, todo código fonte pertence a um pacote. A estrutura de diretórios define a hierarquia de pacotes, e a declaração package no topo de cada arquivo determina a qual pacote ele pertence. Um diretório pode conter múltiplos arquivos, desde que todos declarem o mesmo nome de pacote.
// main.go
package main
import (
"fmt"
"meumodulo/calculadora"
)
func main() {
resultado := calculadora.Somar(2, 3)
fmt.Println("Resultado:", resultado)
}
// calculadora/soma.go
package calculadora
// Somar retorna a soma de dois inteiros
func Somar(a, b int) int {
return a + b
}
Importar pacotes segue caminhos absolutos a partir da raiz do módulo. É possível usar aliases para evitar conflitos de nome:
import (
calc "meumodulo/calculadora"
"fmt"
)
Ciclos de importação ocorrem quando o pacote A importa B, e B importa A (direta ou indiretamente). Go detecta isso em tempo de compilação. Para evitar, reavalie a responsabilidade de cada pacote — extraia interfaces ou mova tipos compartilhados para um pacote comum de menor acoplamento.
2. Introdução aos Módulos com go mod
Um módulo é uma coleção de pacotes Go versionados como uma unidade. O arquivo go.mod na raiz define o caminho do módulo, a versão do Go e as dependências.
Inicialize um módulo:
go mod init github.com/usuario/meuprojeto
Isso gera:
module github.com/usuario/meuprojeto
go 1.22
O versionamento semântico (v1.2.3) é obrigatório para dependências publicadas. Go usa tags Git no formato v1.0.0 para identificar versões.
3. Gerenciamento de Dependências
Adicione uma dependência externa:
go get github.com/gorilla/mux@v1.8.1
O comando go mod tidy limpa dependências não utilizadas e adiciona as faltantes:
go mod tidy
Para atualizar para a versão mais recente:
go get -u github.com/gorilla/mux
Para remover, basta deletar as referências no código e executar go mod tidy.
Pseudo-versões são usadas quando não há tag semântica disponível, no formato v0.0.0-20240301123456-commit_hash:
go get github.com/alguem/lib@commit_hash
4. O Arquivo go.sum e Integridade
O go.sum contém checksums (hash SHA-256) de cada dependência baixada. Ele garante que builds sejam reproduzíveis e seguros contra adulteração.
github.com/gorilla/mux v1.8.1 h1:TuMoUvkRETdXqU+3x7d9pE4gK3c4iA5c3I0i0iK5Y=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
Se o checksum não corresponder, o go build falha. Para resolver conflitos (raro), use:
go mod tidy
Ou remova entradas específicas manualmente e execute go mod verify.
5. Módulos Locais e Substituições
Durante o desenvolvimento, é comum apontar para um módulo local com replace:
module github.com/usuario/meuprojeto
go 1.22
require github.com/usuario/biblioteca v0.0.0
replace github.com/usuario/biblioteca => ../biblioteca-local
Isso permite testar mudanças sem publicar. Para múltiplos módulos no mesmo repositório, cada subdiretório pode ter seu próprio go.mod.
Módulos privados exigem configuração de autenticação no ~/.netrc ou variáveis de ambiente GOPRIVATE:
export GOPRIVATE=github.com/empresa/*
6. Workspaces (Go 1.18+)
Workspaces permitem gerenciar múltiplos módulos simultaneamente sem modificar go.mod de cada um.
go work init ./modulo-a ./modulo-b
Isso cria go.work:
go 1.22
use (
./modulo-a
./modulo-b
)
Adicione mais módulos:
go work use ./modulo-c
Quando usar workspaces vs. replace? Workspaces são ideais para desenvolvimento local de múltiplos módulos inter-relacionados (ex: monorepo). Replace é melhor para ajustes pontuais em dependências específicas sem impacto global.
7. Boas Práticas e Padrões
Organize pacotes por responsabilidade, não por tipo. Evite nomes genéricos como util ou common:
meuprojeto/
├── cmd/
│ └── server/
│ └── main.go
├── internal/
│ ├── auth/
│ ├── db/
│ └── handler/
└── pkg/
└── api/
Nomeação: pacotes devem ter nomes curtos, descritivos e em minúsculo. O nome do pacote deve ser o mesmo do diretório.
Para versionamento v2+, altere o caminho do módulo:
module github.com/usuario/projeto/v2
Isso permite coexistência de versões maiores no mesmo projeto.
Conclusão: O sistema de módulos do Go, combinado com pacotes bem estruturados, oferece um gerenciamento de dependências robusto, seguro e simples. Dominar go mod é essencial para qualquer desenvolvedor Go profissional.
Referências
- Documentação oficial: Pacotes em Go — Guia completo sobre organização de pacotes e importação.
- Tutorial: Introdução a módulos Go — Passo a passo oficial para criar e usar módulos.
- Documentação do
go mod— Referência completa sobre todos os comandos e arquivos do sistema de módulos. - Go Workspaces (Go 1.18+) — Tutorial oficial sobre workspaces e gerenciamento de múltiplos módulos.
- Artigo: Versionamento semântico em módulos Go — Post do blog oficial sobre compatibilidade e versionamento v2+.
- Guia prático: Gerenciando dependências privadas — Como configurar módulos privados com autenticação.
- Referência do
go.sume integridade — Explicação detalhada sobre checksums e verificação de dependências.