Conheça os packages slices e cmp

Com a evolução da linguagem Go, algumas tarefas antes repetitivas ou trabalhosas ganharam abstrações poderosas e idiomáticas. Os packages slices e cmp, adicionados oficialmente ao ecossistema da linguagem por meio do módulo golang.org/x/exp e posteriormente promovidos ao módulo padrão em versões mais recentes, são dois exemplos reais.

Neste post, vamos explorar como esses dois packages podem simplificar tarefas comuns como ordenações e comparações, trazendo clareza, concisão e segurança ao seu código.

O package slices

O package slices, inicialmente disponível em golang.org/x/exp/slices e depois promovido ao slices, fornece funções genéricas para manipulação de slices de forma mais expressiva e segura. Entre suas funcionalidades estão: busca, ordenação, filtro, comparação, cópia e mais.

Exemplo: ordenando uma lista de structs

Considere uma situação em que você precisa ordenar uma lista de usuários por idade. Antes dos packages slices e cmp, você provavelmente usaria sort.Slice assim:

package main

import (
	"fmt"
	"sort"
)

type User struct {
	Name string
	Age  int
}

func main() {
	users := []User{
		{"Alice", 30},
		{"Bob", 22},
		{"Carol", 25},
	}

	sort.Slice(users, func(i, j int) bool {
		return users[i].Age < users[j].Age
	})

	for _, user := range users {
		fmt.Printf("%s (%d)\\n", user.Name, user.Age)
	}
}

Esse código funciona bem, mas não é tão idiomático e seguro quanto poderia ser. O uso explícito de índices pode causar bugs sutis, especialmente em slices maiores ou funções de comparação mais complexas.

O package cmp

O package cmp fornece uma maneira genérica, segura e concisa de fazer comparações entre valores — especialmente útil dentro de funções como slices.SortFunc.

Vamos reescrever o exemplo anterior usando slices.SortFunc em conjunto com cmp.Compare:

package main

import (
	"fmt"
	"cmp"
	"slices"
)

type User struct {
	Name string
	Age  int
}

func main() {
	users := []User{
		{"Alice", 30},
		{"Bob", 22},
		{"Carol", 25},
	}

	slices.SortFunc(users, func(a, b User) int {
		return cmp.Compare(a.Age, b.Age)
	})

	for _, user := range users {
		fmt.Printf("%s (%d)\\n", user.Name, user.Age)
	}
}

Entendendo o cmp.Compare

O cmp.Compare retorna:

  • -1 se a < b
  • 0 se a == b
  • 1 se a > b

Essa abordagem traz diversas vantagens:

  • Mais expressividade: em vez de se preocupar com expressões booleanas, você trabalha com um comparador genérico.
  • Reutilização: funções genéricas podem ser compostas e reutilizadas.
  • Redução de erros: menos risco de acessar índices incorretos ou escrever comparações erradas.

Conclusão

Os packages slices e cmp representam um avanço na direção de um Go mais moderno, seguro e idiomático. Eles são especialmente úteis em contextos onde manipulamos coleções de dados de forma recorrente, o que é algo comum em aplicações reais.

Ao adotá-los, você ganha:

  • Redução de boilerplate
  • Aumento na legibilidade do código
  • Maior aderência ao estilo idiomático da linguagem

Se você ainda não os incorporou no seu dia a dia, vale a pena experimentá-los em seus projetos. Essas abstrações não só tornam o código mais limpo, como também reduzem bugs e aumentam a produtividade.

Para saber mais sobre esses dois packages, acesse a documentação oficial:

Gostou do conteúdo?

  • Inscreva-se na nossa newsletter para receber mais dicas práticas sobre Go, Kubernetes e desenvolvimento de software diretamente no seu e-mail!
  • 🚀 Torne-se um assinante pago do blog e tenha acesso a conteúdos exclusivos, como tutoriais avançados, estudos de caso e muito mais!

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.

Livros Recomendados

Abaixo listei alguns dos melhores livros que já li sobre arquitetura de software e desenvolvimento.

Deixe uma resposta