Fundamentos de Genéricos
10 ejemplos para empezar con Genéricos - 7 básicos y 3 intermedios.
Busca en todas las páginas de la documentación
10 ejemplos para empezar con Genéricos - 7 básicos y 3 intermedios.
slices/maps/cmp necesitan Go 1.21+.mkdir gdemo && cd gdemo && go mod init example.com/gdemo.main.go y ejecútalos con go run ..Un parámetro de tipo T con la restricción cmp.Ordered habilita < en números y cadenas.
package main
import (
"cmp"
"fmt"
)
func Max[T cmp.Ordered](a, b T) T {
if a > b {
return a
}
return b
}
func main() {
fmt.Println(Max(3, 7), Max("a", "z"))
}cmp.Ordered es una restricción de la biblioteca estándar para tipos ordenados.T a partir de los argumentos en el sitio de la llamada.Relacionado: Genéricos en Go: Restricciones sin Plantillas - modelo mental para restricciones
Pasa argumentos de tipo cuando la inferencia sea ambigua.
package main
import "fmt"
func Zero[T any]() T {
var z T
return z
}
func main() {
fmt.Printf("%v %q\n", Zero[int](), Zero[string]())
}any es la restricción que acepta todos los tipos.Zero[int]() sustituye T por int.T sin reflexión.Relacionado: Parámetros de Tipo e Interfaces de Restricción -
anyy restricciones nombradas
Itera con range sin índice sobre []T.
package main
import "fmt"
func Contains[T comparable](s []T, v T) bool {
for _, x := range s {
if x == v {
return true
}
}
return false
}
func main() {
fmt.Println(Contains([]string{"a", "b"}, "b"))
}comparable permite == y != en T.T en sí mismo no puede ser un tipo de slice en un rol de clave de mapa comparable.slices.Contains de la biblioteca estándar en código de producción.Relacionado: Conjuntos de Tipos y la Restricción comparable - lo que permite
comparable
Los parámetros de tipo en los tipos struct se aplican a los métodos.
package main
import "fmt"
type Stack[T any] struct {
items []T
}
func (s *Stack[T]) Push(v T) { s.items = append(s.items, v) }
func (s *Stack[T]) Pop() (T, bool) {
if len(s.items) == 0 {
var zero T
return zero, false
}
v := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return v, true
}
func main() {
var st Stack[int]
st.Push(1)
v, _ := st.Pop()
fmt.Println(v)
}Stack[T] usan el mismo T que el struct.Stack[int], Stack[string]) es un tipo distinto.Stack[int]{} está listo para usarse.Relacionado: Estructuras de Datos Genéricas: Sets, Queues, Maps - contenedores reutilizables
Las restricciones pueden requerir métodos, no solo uniones de tipos.
package main
import "fmt"
type Stringer interface {
String() string
}
func Join[T Stringer](items []T, sep string) string {
if len(items) == 0 {
return ""
}
out := items[0].String()
for _, it := range items[1:] {
out += sep + it.String()
}
return out
}
type ID int
func (id ID) String() string { return fmt.Sprintf("id:%d", int(id)) }
func main() {
fmt.Println(Join([]ID{1, 2}, ","))
}T Stringer significa que cada T debe implementar String() string.implements.T están permitidas porque están en la restricción.Relacionado: Parámetros de Tipo e Interfaces de Restricción - restricciones de métodos
Construye una tabla de frecuencia con clave T.
package main
import "fmt"
func Count[T comparable](items []T) map[T]int {
m := make(map[T]int)
for _, v := range items {
m[v]++
}
return m
}
func main() {
fmt.Println(Count([]string{"a", "b", "a"}))
}comparable.Relacionado: Conjuntos de Tipos y la Restricción comparable - reglas para claves de mapa
La declaración de variable corta elige la instancia.
package main
import "fmt"
type Pair[A, B any] struct {
First A
Second B
}
func main() {
p := Pair[string, int]{"go", 1}
fmt.Println(p.First, p.Second)
}[A, B any].Relacionado: Estructuras de Datos Genéricas: Sets, Queues, Maps - contenedores multiparámetro
Acepta tipos nombrados basados en su tipo subyacente.
package main
import "fmt"
type Celsius float64
type Fahrenheit float64
type Number interface {
~float64
}
func Double[T Number](v T) T {
return v * 2
}
func main() {
fmt.Println(Double(Celsius(10)), Double(Fahrenheit(20)))
}~float64 incluye Celsius y Fahrenheit porque su tipo subyacente es float64.~, solo el tipo literal float64 coincidiría.Relacionado: Parámetros de Tipo e Interfaces de Restricción - profundidad del operador
~
Los tipos de unión listan los tipos concretos permitidos.
package main
import "fmt"
type Integer interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
func Abs[T Integer](v T) T {
if v < 0 {
return -v
}
return v
}
func main() {
fmt.Println(Abs(int8(-3)), Abs(int64(-9)))
}| construye una unión dentro de una restricción de interfaz.Relacionado: Parámetros de Tipo e Interfaces de Restricción - límites de la unión
Busca primero los ayudantes genéricos de la biblioteca estándar antes de hacer copias personalizadas.
package main
import (
"fmt"
"slices"
)
func main() {
nums := []int{1, 2, 3}
fmt.Println(slices.Contains(nums, 2))
fmt.Println(slices.Index(nums, 9))
}slices y maps son APIs genéricas primero en Go 1.21+.Relacionado: Algoritmos Genéricos: Paquetes slices, maps y cmp - catálogo de la biblioteca estándar
Versiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado de Green Tea GC, go fix modernizers - verificar parche en la compilación), chi (última versión - verificar en la compilación), gin (última versión - verificar en la compilación), echo (última versión - verificar en la compilación), google.golang.org/grpc (última versión - verificar en la compilación), sigs.k8s.io/controller-runtime (última versión - verificar en la compilación), kubebuilder (última versión - verificar en la compilación), tinygo (última versión - verificar objetivos de placa en la compilación), wazero (última versión - verificar en la compilación) y golangci-lint (última versión - verificar conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 19 jul 2026