Novo new() com expressão inicial no Go 1.26

Neste post, vamos explorar uma mudança pequena, mas poderosa, que chegou no Go 1.26: o built-in new() agora aceita uma expressão como valor inicial. Pode parecer um detalhe, mas simplifica inicializações e abre espaço para padrões de código mais elegantes.

O que é o built-in new()?

O new() é uma função built-in que aloca memória para um tipo e retorna um ponteiro inicializado com o valor zero do tipo. Historicamente, você só podia passar um tipo para new().

Como era antes (Go 1.25 e anteriores)

Antes, se você quisesse alocar memória e inicializar com um valor específico, tinha duas opções:

// Opção 1: alocar e depois atribuir
p := new(int)
*p = 42

// Opção 2: usar composição literal com &
p := &int{42}  // Só funciona com tipos estruturados

Para tipos simples como int, string, você era forçado a alocar e depois atribuir, o que gerava duas linhas desnecessárias.

A novidade no Go 1.26

No Go 1.26, new() agora aceita uma expressão como argumento. Veja:

// Antes (Go 1.25)
p := new(int)
*p = 42

// Agora (Go 1.26)
p := new(42)

Simples e direto. O new() aloca memória para um int e inicializa com 42 em uma única operação.

Exemplos práticos

Com tipos primitivos

// Ponteiro para string
name := new("Tiago")
fmt.Println(*name)  // Output: Tiago

// Ponteiro para float64
price := new(99.99)
fmt.Println(*price)  // Output: 99.99

// Ponteiro para bool
active := new(true)
fmt.Println(*active)  // Output: true

Com tipos estruturados

type User struct {
    Name string
    Age  int
}

// Antes
u := new(User)
u.Name = "Alice"
u.Age = 30

// Agora
u := new(User{Name: "Alice", Age: 30})

Com arrays e slices

// Ponteiro para array inicializado
arr := new([5]int{1, 2, 3, 4, 5})
fmt.Println(arr[0])  // Output: 1

// Ponteiro para slice inicializado
sl := new([]int{10, 20, 30})
fmt.Println((*sl)[1])  // Output: 20

Por que isso importa?

1. Menos linhas, mais clareza

Alocar e inicializar em uma operação deixa a intenção mais clara. Você não precisa de duas linhas para algo que é conceitualmente uma operação única.

2. Padrões idiomáticos simplificados

Alguns padrões comuns no Go agora ficam mais elegantes. Por exemplo, criar um ponteiro para um valor literal é agora trivial:

// Útil em configurações ou testes
config := new(Config{
    Timeout: 30 * time.Second,
    Retries: 3,
})

3. Menos erros de inicialização

Ao fazer tudo em uma operação, você reduz a chance de esquecer a inicialização:

// Risco de esquecer a inicialização
p := new(int)
// oops, esqueci de inicializar

// Com a nova sintaxe, é obrigatório pensar nisso
p := new(0)  // claro e direto

Quando usar?

Essa feature é mais útil em cenários onde você precisa de um ponteiro (passando para funções que esperem *T, ou para garantir identidade), mas quer inicializar com um valor específico.

// Função que espera um ponteiro
func UpdateUser(u *User) error {
    u.LastUpdate = time.Now()
    return db.Save(u)
}

// Agora você pode fazer em uma linha
err := UpdateUser(new(User{Name: "Bob", Age: 25}))

Conclusão

A nova sintaxe do new() no Go 1.26 é um exemplo perfeito de como mudanças pequenas podem melhorar a experiência de desenvolvimento. Não é uma revolução, mas torna o código mais limpo e reduz o boilerplate em inicializações comuns.

Se você trabalha com muitos ponteiros ou precisa alocar e inicializar valores em uma operação, essa é uma mudança bem-vinda. Vale a pena testar no seu próximo projeto com Go 1.26.


Gostou do conteúdo?

  • Inscreva-se na newsletter para receber mais dicas práticas sobre Go diretamente no seu e-mail!
  • 🚀 Conheça a Imersão Golang e leve seus conhecimentos em Go para o próximo nível!

Faça parte da comunidade!

Receba os melhores conteúdos sobre Go, Kubernetes, arquitetura de software, Cloud e esteja sempre atualizado com as tendências e práticas do mercado.

* indicates required

Deixe uma resposta