O artigo do blog oficial do Go discute a nova versão do go fix, introduzida no Go 1.26, e como essa ferramenta pode ser usada para modernizar automaticamente o código Go, aproveitando os recursos mais recentes da linguagem e da biblioteca padrão. O artigo também aborda a infraestrutura por trás do go fix e como ela está evoluindo, além de apresentar o conceito de ferramentas de análise “self-service” para ajudar os mantenedores de módulos e organizações a codificar suas próprias diretrizes e boas práticas.
Executando o go fix
O comando go fix funciona de forma semelhante ao go build e go vet, aceitando padrões que denotam pacotes. Para corrigir todos os pacotes no diretório atual e seus subdiretórios, execute:
go fix ./...
O go fix atualiza silenciosamente os arquivos de código-fonte, descartando quaisquer correções em arquivos gerados, pois nesses casos a correção apropriada deve ser feita na lógica do próprio gerador. É recomendado executar o go fix em seu projeto cada vez que você atualizar para uma versão mais recente do toolchain Go. Como o comando pode corrigir centenas de arquivos, é aconselhável começar com um estado limpo do Git, para que as mudanças consistam apenas nas edições do go fix.
Para visualizar as alterações que o comando faria, use a flag -diff:
go fix -diff ./...
Isso exibirá um diff mostrando as mudanças propostas.
Para listar os fixers disponíveis, execute:
go tool fix help
Para obter documentação detalhada sobre um fixer específico, adicione seu nome ao comando help:
go tool fix help forvar
Por padrão, o comando go fix executa todos os analyzers. Para executar apenas analyzers específicos, use as flags correspondentes aos seus nomes (por exemplo, -any). Para executar todos os analyzers, exceto os selecionados, negue as flags (por exemplo, -any=false).
Como com go build e go vet, cada execução do comando go fix analisa apenas uma configuração de build específica. Se seu projeto faz uso intensivo de arquivos marcados para diferentes CPUs ou plataformas, você pode executar o comando mais de uma vez com diferentes valores de GOARCH e GOOS para uma melhor cobertura:
GOOS=linux GOARCH=amd64 go fix ./...
GOOS=darwin GOARCH=arm64 go fix ./...
GOOS=windows GOARCH=amd64 go fix ./...
Executar o comando mais de uma vez também oferece oportunidades para correções sinérgicas.
Modernizers
A introdução de generics no Go 1.18 marcou o início de um período de mudanças mais rápidas, especialmente nas bibliotecas. Muitos dos loops triviais que os programadores Go rotineiramente escrevem, como para coletar as chaves de um map em um slice, agora podem ser convenientemente expressos como uma chamada para uma função genérica como maps.Keys. Consequentemente, esses novos recursos criam muitas oportunidades para simplificar o código existente.
Para garantir que os futuros modelos de aprendizado de máquina (LLMs) sejam treinados com os idioms mais recentes, é necessário garantir que esses idioms sejam refletidos nos dados de treinamento, ou seja, no corpus global de código Go de código aberto.
Ao longo do último ano, foram construídos dezenas de analyzers para identificar oportunidades de modernização. Aqui estão três exemplos das correções que eles sugerem:
minmax: Substitui uma instrução
ifpor uma chamada às funçõesminoumaxdo Go 1.21:x := f() if x < 0 { x = 0 } if x > 100 { x = 100 }Se torna:
x := min(max(f(), 0), 100)rangeint: Substitui um loop
forde 3 cláusulas por um looprangesobre int do Go 1.22:for i := 0; i < n; i++ { f() }Se torna:
for range n { f() }stringscut: Substitui usos de
strings.Indexe slicing porstrings.Cutdo Go 1.18:i := strings.Index(s, ":") if i >= 0 { return s[:i] }Se torna:
before, _, ok := strings.Cut(s, ":") if ok { return before }
Esses modernizers estão incluídos no gopls, para fornecer feedback instantâneo enquanto você digita, e no go fix, para que você possa modernizar vários pacotes inteiros de uma só vez em um único comando. Além de tornar o código mais claro, os modernizers podem ajudar os programadores Go a aprender sobre os recursos mais recentes. Como parte do processo de aprovação de cada nova alteração na linguagem e na biblioteca padrão, o grupo de revisão de proposals agora considera se ela deve ser acompanhada por um modernizer. Espera-se adicionar mais modernizers a cada lançamento.
Exemplo: um modernizer para o new(expr) do Go 1.26
O Go 1.26 inclui uma pequena, mas amplamente útil, alteração na especificação da linguagem. A função built-in new cria uma nova variável e retorna seu endereço. Historicamente, seu único argumento era obrigado a ser um tipo, como new(string), e a nova variável era inicializada com seu valor “zero”, como "". No Go 1.26, a função new pode ser chamada com qualquer valor, fazendo com que ela crie uma variável inicializada com esse valor, evitando a necessidade de uma instrução adicional. Por exemplo:
ptr := new(string)
*ptr = "go1.25"
Se torna:
ptr := new("go1.26")
Esse recurso preencheu uma lacuna que vinha sendo discutida há mais de uma década e resolveu uma das proposals mais populares para uma mudança na linguagem. É especialmente conveniente em código que usa um tipo ponteiro *T para indicar um valor opcional do tipo T, como é comum ao trabalhar com pacotes de serialização como json.Marshal ou protocol buffers. Esse é um padrão tão comum que a equipe do Go criou um modernizer para ele.
Infraestrutura de Análise e “Self-Service”
O artigo também destaca a infraestrutura por trás do go fix, que é baseada no pacote golang.org/x/tools/go/analysis. Essa infraestrutura permite a criação de analyzers personalizados para identificar e corrigir padrões de código específicos. A ideia de “self-service” significa que os mantenedores de módulos e organizações podem criar seus próprios analyzers para impor suas próprias diretrizes e boas práticas.
Isso é particularmente útil para:
- Consistência de código: Garantir que todos os membros de uma equipe sigam as mesmas convenções de codificação.
- Prevenção de erros: Identificar padrões de código que são propensos a erros.
- Aplicação de políticas: Garantir que o código esteja em conformidade com as políticas de segurança ou conformidade da organização.
Ao permitir que as organizações criem seus próprios analyzers, o go fix se torna uma ferramenta ainda mais poderosa para melhorar a qualidade e a consistência do código Go.
Artigo Original
Este e um resumo em português do artigo original publicado no blog oficial do Go.
Titulo original: Using go fix to modernize Go code
Leia o artigo completo em ingles no Go Blog
Autor original: Alan Donovan