Tecnologias/01 - Linguagens/01 - Go6 min
Versões, Módulos e Compatibilidade
Conceito
Quando uma vaga pede "Go 1.27", ela quase nunca está pedindo uma feature específica de 1.27 — está dizendo "usamos Go atual, não um projeto parado em 1.16". Vale entender o mecanismo por trás disso, porque ele é incomum entre linguagens.
O ciclo: duas releases por ano, sempre
Go lança em fevereiro e agosto, na data, com o que estiver pronto. Nada de esperar uma feature grande.
| Versão | Data |
|---|---|
| Go 1.26.0 | 10/02/2026 |
| Go 1.27.0 | 19/08/2026 |
| Go 1.27.1 | 01/09/2026 |
Suporte: as duas majors mais recentes recebem correções de segurança. Hoje, isso é 1.27 e 1.26 — o 1.25 já saiu da janela. É por isso que "estar em Go atual" é uma exigência de segurança, não de moda.
A promessa de compatibilidade Go 1
Código que compila com Go 1.x continua compilando e funcionando em Go 1.y (y > x).
Essa é a promessa mais valiosa e mais caríssima do Go. Ela é o motivo de:
- atualizar a toolchain ser rotina, não projeto;
interface{}continuar existindo depois deany;- decisões ruins de 2012 (o pacote
math/randv1, a API detime.After) nunca terem sido corrigidas — só duplicadas emv2.
E existe uma válvula de escape para quando o comportamento precisa mudar: GODEBUG.
Se uma correção de bug pode quebrar programas que dependiam do bug, o Go mantém o
comportamento antigo acessível por GODEBUG=algo=1, e usa a diretiva go do go.mod
para decidir o padrão. Ou seja: a sua go.mod seleciona a semântica, não só a
sintaxe.
Módulos: MVS, não resolução de ranges
Aqui o Go difere de npm, pip e Maven de um jeito importante:
go.mod → requisitos mínimos declarados
go.sum → hash de tudo, verificável
O algoritmo é MVS (Minimal Version Selection): para cada dependência, o Go escolhe
a maior das versões mínimas exigidas por alguém no grafo. Não existe intervalo
(^1.2), não existe resolvedor SAT, não existe "atualizou sozinho na CI".
| Go (MVS) | npm/Cargo (ranges) | |
|---|---|---|
| Build reprodutível | por construção | precisa de lockfile |
| Atualização | só explícita (go get -u) |
pode acontecer no install |
| Seleção de versão | uma versão por caminho de módulo; compatibilidade ainda precisa ser verificada | resolvedor considera os requisitos declarados |
| Dois majors juntos | permitido (/v2 no path) |
por nesting |
Trade-offs
A promessa Go 1 é uma dívida acumulada. A biblioteca padrão carrega APIs que ninguém
recomenda mais, e o preço aparece na forma de v2 convivendo com v1 (math/rand/v2,
encoding/json/v2). Você precisa saber qual está usando.
GODEBUG esconde mudanças de comportamento. É o que permite evoluir sem quebrar — e
também o que faz um programa mudar de comportamento só por você ter subido a diretiva
go no go.mod, sem trocar uma linha de código.
MVS é conservador de propósito. Você fica em versões antigas até pedir para sair.
Ótimo para reprodutibilidade, ruim para receber correções de segurança sem esforço — daí
govulncheck e Dependabot serem parte do fluxo, não luxo.
O trade-off central: Go escolheu estabilidade sobre limpeza. Todo desconforto de API na biblioteca padrão é o preço de você poder atualizar a toolchain numa terça-feira à tarde.
Exemplo prático
O que o Go 1.27 trouxe
Linguagem
- Métodos genéricos: um método pode declarar os próprios parâmetros de tipo (ex.:
(*Rand).N[Int intType](Int) Intemmath/rand/v2). Interfaces continuam sem poder declarar métodos genéricos. - Chaves em literais de struct podem ser qualquer seletor de campo válido, não só nomes de campo do topo — funciona bem com embedding.
- Inferência de tipo generalizada: vale agora em todo contexto onde uma função genérica é atribuída a variável ou convertida para um tipo de função compatível.
Biblioteca
encoding/jsonpassou a ser implementado pela v2 por padrão. Novos pacotes:encoding/json/v2(API comOptionsvariádicos) eencoding/json/jsontext(nível sintático). Saída de emergência:GOEXPERIMENT=nojsonv2.- Pacote
uuidna biblioteca padrão: gera e faz parse de UUID. crypto/mldsa: ML-DSA (FIPS 204), assinatura pós-quântica, com suporte emcrypto/x509.
Runtime e diagnóstico
- Perfil
goroutineleakagora estável emruntime/pprofe em/debug/pprof/goroutineleak. Ver 2. Goroutines e Channels. - Alocação especializada por tamanho: alocações pequenas (< 80 bytes) até 30% mais baratas; binário cresce ~60 KB. Saída:
GOEXPERIMENT=nosizespecializedmalloc(deve sair no 1.28). GODEBUG=asynctimerchanfoi removido: canais do pacotetimesão sempre sem buffer.- SIMD experimental (
simd/archsimd) ganhou arm64 Neon e WebAssembly.
Ferramentas
go testroda o vetstdversionpor padrão.go docaceitapacote@versãoe tem-expara listar exemplos executáveis.go fixganhou modernizadores (atomictypes,embedlit,slicesbackward,unsafefuncs);waitgroupvirouwaitgroupgo.go mod tidyreorganiza osrequireem dois blocos (diretas e indiretas).go tool trace -httpagora escuta só em localhost por padrão.- O
gonão suporta maisbzr.
JSON no 1.27: implementação e contrato público
O pacote encoding/json passa a usar a implementação v2, preservando o comportamento
de marshal/unmarshal da API v1. O texto exato de erros pode mudar. Já usar diretamente
encoding/json/v2 adota padrões mais estritos, salvo opções explícitas de compatibilidade:
| Entrada | API encoding/json |
API encoding/json/v2, padrões próprios |
|---|---|---|
| UTF-8 inválido numa string | aceitava (substituía) | rejeita |
Nome duplicado no objeto ({"a":1,"a":2}) |
aceitava (último vence) | rejeita |
Ao migrar explicitamente para a API v2, teste mensagens de produtores legados e histórico de Kafka. Rejeitar uma entrada passa a ser decisão do parser; traduzir o erro em resposta HTTP é responsabilidade da aplicação. Atualizar a toolchain mantendo a API v1 não deve ser descrito como adoção automática dos padrões estritos da v2. Referência: notas oficiais do Go 1.27.
Checklist de atualização de toolchain
go version # onde estou
go get go@1.27.1 # sobe a diretiva go e a toolchain
go mod tidy # no 1.27, também reorganiza os require
go build ./... && go test ./... # o de sempre
go vet ./... # stdversion agora roda no go test também
govulncheck ./... # o passo que a maioria esquece
GOEXPERIMENT=nojsonv2 go test ./... # se algo de JSON quebrou, confirma a causa
go do go.mod não é decoraçãoEla define (a) qual sintaxe da linguagem é permitida e (b) quais padrões de GODEBUG
valem. Subir de go 1.21 para go 1.27 pode mudar comportamento de runtime. Suba de
propósito, num commit só seu, com os testes ao lado.
Aprofundamento aplicado
MVS em um grafo concreto
aplicação exige biblioteca A v1.2
aplicação exige biblioteca B v1.0
B v1.0 exige A v1.4
versão selecionada de A: v1.4
A seleção satisfaz a maior exigência mínima. Isso não prova que A v1.4 respeitou todos os contratos comportamentais usados pela aplicação. Um fornecedor pode introduzir uma regressão dentro do mesmo major; por isso a seleção determinística não substitui testes.
go.sum registra verificações de conteúdo e pode listar versões que não participam
do build atual. Para entender a seleção, examine go list -m all e go mod graph.
Um replace local também pode alterar o código compilado sem representar o que um
consumidor externo da biblioteca obterá.
Referência: seleção de versões e replace.
Exercício: desenhe três módulos com exigências diferentes para uma dependência. Resultado esperado: consiga prever a versão selecionada e explicar separadamente como verificar integridade, compatibilidade e a versão da toolchain.
Relacionado
Parte de MOC Go · go.dev/doc/go1.27 · Histórico de releases