Algoritmos Genéricos: Paquetes slices, maps y cmp
Go 1.21 añadió slices, maps y cmp - paquetes de la biblioteca estándar con enfoque genérico para ordenar, buscar, clonar y comparar de tres vías.
Busca en todas las páginas de la documentación
Go 1.21 añadió slices, maps y cmp - paquetes de la biblioteca estándar con enfoque genérico para ordenar, buscar, clonar y comparar de tres vías.
Úsalos antes que helpers personalizados; amplía con tus propios genéricos solo para la lógica de dominio que no cubran.
slices opera sobre []E con restricciones como cmp.Ordered o comparable.
maps proporciona copia, eliminación e igualdad para map[K]V.
cmp define Ordered, Compare y Or para construir restricciones y comparadores.
Los algoritmos personalizados siguen los mismos patrones: un parámetro de tipo para elementos, parámetros separados para claves y valores cuando sea necesario.
Tarjeta de referencia rápida - lista para copiar y pegar.
import (
"cmp"
"slices"
)
func TopN[T cmp.Ordered](data []T, n int) []T {
if n <= 0 {
return nil
}
cp := slices.Clone(data)
slices.Sort(cp)
if n > len(cp) {
n = len(cp)
}
return cp[len(cp)-n:]
}Cuándo recurrir a esto:
cmp.Ordered en lugar de copiar uniones grandes.package main
import (
"cmp"
"fmt"
"maps"
"slices"
)
type User struct {
Name string
Age int
}
func main() {
nums := []int{3, 1, 4, 1, 5}
slices.Sort(nums)
fmt.Println(nums)
fmt.Println(slices.BinarySearch(nums, 4))
m1 := map[string]int{"a": 1, "b": 2}
m2 := maps.Clone(m1)
m2["c"] = 3
fmt.Println(maps.Equal(m1, m2))
users := []User{{"ann", 30}, {"bob", 25}}
slices.SortFunc(users, func(a, b User) int {
return cmp.Compare(a.Age, b.Age)
})
fmt.Println(users)
}Lo que esto demuestra:
slices.Sort requiere elementos ordenables; SortFunc acepta comparadores personalizados que devuelven el signo de cmp.maps.Clone y maps.Equal evitan la copia/igualdad hechas a mano.cmp.Compare en los campos, no == en structs a menos que sean completamente comparables y ese sea el orden deseado.slices mutan los slices en el lugar a menos que el nombre diga Clone o devuelva un nuevo slice.maps no copian valores en profundidad; los punteros y slices dentro de los valores se aliásan como una asignación de mapa ordinaria.cmp.Compare devuelve -1, 0 o 1 para tipos ordenados y es el tipo de retorno preferido del comparador para slices.SortFunc.slices| Función | Propósito |
|---|---|
Sort, SortFunc | Ordenación en el lugar |
BinarySearch, BinarySearchFunc | Búsqueda en slice ordenado |
Contains, Index | Búsqueda lineal |
Clone, Compact, Delete | Operaciones de memoria de slice |
Insert, Replace | Ediciones estructurales |
maps| Función | Propósito |
|---|---|
Clone | Copia superficial del mapa |
Copy | Fusión en el destino |
Equal | Igualdad profunda de claves y valores |
DeleteFunc | Eliminar por predicado |
cmp| Símbolo | Propósito |
|---|---|
cmp.Ordered | Restricción para tipos integrados ordenados y tipos subyacentes |
cmp.Compare(x, y) | Comparación de tres vías para tipos ordenados |
cmp.Or(x, y, …) | Elegir el primer resultado de comparación distinto de cero en claves de ordenación |
// Ordenación de claves múltiples con cmp.Or
slices.SortFunc(records, func(a, b Record) int {
return cmp.Or(
cmp.Compare(a.Region, b.Region),
cmp.Compare(a.Name, b.Name),
)
})slices.SortFunc sobre sort.Slice para código nuevo - firmas de comparador más claras.slices.SortStableFunc se ajusta a tu versión de Go y úsalo cuando elementos iguales deban mantener el orden de entrada.Map siguen siendo útiles: func Map[T, U any](in []T, f func(T) U) []U.== en structs - Usa SortFunc con orden de campos explícito. Solución: cmp.Or en campos.maps.Clone hace copia profunda - Los valores se aliásan. Solución: clona estructuras anidadas explícitamente cuando sea necesario.cmp.Ordered.range en un algoritmo personalizado - Omite elementos o provoca condiciones de carrera. Solución: bucles basados en índices o recopila índices primero.maps.Copy - Pánico al escribir en un mapa nulo. Solución: dst = make(map[K]V) antes de copiar.| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
Paquete sort | Código heredado, tipos no-slice | Código nuevo solo para slices |
| Bucles escritos a mano | Pequeño caso único en ruta caliente ya inlined | Algoritmo repetido entre tipos |
Experimentos de x/exp/slices | Características de vanguardia | Producción sin revisión |
| Estructuras de datos de dominio específico (árbol/índice) | Estadísticas de orden más allá de la ordenación de slices | Lotes simples en memoria |
Siempre para el mantenimiento de producción - la biblioteca estándar sigue las versiones y optimizaciones de Go.
Los genéricos personalizados para líneas únicas rara vez valen la pena.
Sort necesita elementos cmp.Ordered.
SortFunc acepta cualquier tipo de elemento con una función comparadora.
Sí - nuevo array subyacente.
Úsalo cuando debas desvincularte de la memoria del llamador.
Dos mapas nulos son iguales.
Un mapa nulo y un mapa no nulo vacío no son iguales.
Devuelve la primera comparación no cero en una cadena.
Ideal para ordenaciones lexicográficas de campos múltiples.
byte está ordenado.
Sort funciona; recuerda que el paquete bytes también tiene helpers especializados.
El soporte varía según la versión y la placa.
Verifica en CI para objetivos embebidos.
Un Map simple de []T a []U son unas pocas líneas.
Filter devuelve un slice recortado o se añade a un buffer preasignado.
Encuentra cualquier índice coincidente en datos ordenados.
Camina por los vecinos si necesitas todos los elementos iguales.
Sí, para listas de encabezados, métodos permitidos y ordenación de segmentos de ruta en pruebas.
Mantén las firmas de los manejadores no genéricas.
Cuerpos monomorfizados pequeños a menudo se inlined como código escrito a mano.
Haz benchmark si tienes dudas.
slices.SortFunc con comparadores cmp.Compare o cmp.Or.
slices.Containscmp.Orderedcomparable - maps.Equal vs ==Versiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado Green Tea GC, go fix modernizers - verifica el parche en la compilación), chi (última - verifica en la compilación), gin (última - verifica en la compilación), echo (última - verifica en la compilación), google.golang.org/grpc (última - verifica en la compilación), sigs.k8s.io/controller-runtime (última - verifica en la compilación), kubebuilder (última - verifica en la compilación), tinygo (última - verifica los objetivos de placa en la compilación), wazero (última - verifica en la compilación) y golangci-lint (última - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 18 jul 2026