A ordenação de elementos em um array é uma tarefa frequentemente utilizada em diversos programas. Embora existam muitos algoritmos de ordenação bem conhecidos, ninguém quer ficar copiando blocos de código de um projeto para outro.
Por isso, o Go oferece a biblioteca nativa sort.
Ela permite ordenar arrays in-place (a ordenação é feita diretamente na estrutura de dados original, sem criar uma cópia adicional do array) com qualquer critério de ordenação, utilizando uma abordagem baseada em interfaces.
A função sort.Sort não faz suposições sobre a estrutura dos dados; ela apenas exige que o tipo a ser ordenado implemente a interface sort.Interface, que define três métodos essenciais apresentados a seguir.
Um ótimo exemplo inicial é o tipo sort.StringSlice, fornecido pela própria biblioteca sort. Ele já implementa a interface sort.Interface, conforme mostrado abaixo:
Seguindo essas regras, é possível ordenar structs com base em seus campos como no exemplo a seguir, que ordena uma lista de alunos pela nota:
Com a estrutura já definida, também é possível verificar se o array está ordenado usando sort.IsSorted, além de realizar a ordenação em ordem reversa com sort.Reverse. As funções são demonstradas abaixo, utilizando a mesma estrutura do exemplo anterior.
A biblioteca também oferece outras funções bastante úteis:
Ints(x []int): ordena uma slice de inteiros em ordem crescente.
IntsAreSorted(x []int) bool: verifica se o slice x está ordenada em ordem crescente.
Strings(x []string): ordena um slice de strings em ordem crescente.
StringsAreSorted(x []string) bool: verifica se a slice x está ordenada em ordem crescente.
ATENÇÃO
Na própria documentação do pacote sort, na data de escrita deste artigo, existe uma nota na função sort.Sort que diz o seguinte:
Em muitas situações, a função mais recente slices.SortFunc é mais ergonômica e apresenta melhor desempenho.
Essa mesma nota se encontra na função sort.IsSorted:
Em muitas situações, a função mais recente slices.IsSortedFunc é mais ergonômica e apresenta melhor desempenho.
Em ambos os casos, recomendo avaliar qual abordagem adotar com base no que for mais vantajoso para a sua situação: a simplicidade das funções do pacote sort ou a possível otimização oferecida pelo pacote slices.
Para descobrir qual delas apresenta melhor desempenho no seu contexto, utilize os benchmarks do Go (fica aqui o dever de casa para você, caro leitor, dar uma conferida nisso).
A partir do Go 1.22, algumas funções do pacote sort já utilizam a biblioteca slices internamente, como é o caso de sort.Ints, que usa slices.Sort, e sort.IntsAreSorted, que usa slices.IsSorted.
Para saber mais, confira as documentações oficiais: