Noções Básicas de Genéricos
10 exemplos para você começar com Genéricos - 7 básicos e 3 intermediários.
Busque em todas as páginas da documentação
10 exemplos para você começar com Genéricos - 7 básicos e 3 intermediários.
slices/maps/cmp precisam do Go 1.21+.mkdir gdemo && cd gdemo && go mod init example.com/gdemo.main.go e execute com go run ..Um parâmetro de tipo T com a restrição cmp.Ordered habilita < em números e strings.
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 é uma restrição da biblioteca padrão para tipos ordenados.T a partir dos argumentos no local da chamada.Relacionado: Genéricos em Go: Restrições Sem Templates - modelo mental para restrições
Passe argumentos de tipo quando a inferência for ambígua.
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 é a restrição que aceita todos os tipos.Zero[int]() substitui T por int.T é retornado sem reflexão.Relacionado: Parâmetros de Tipo e Interfaces de Restrição -
anye restrições nomeadas
Itere com range sem í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 == e != em T.T em si não pode ser um tipo slice em uma função de chave de mapa comparable.slices.Contains da biblioteca padrão em código de produção.Relacionado: Conjuntos de Tipos e a Restrição comparable - o que
comparablepermite
Parâmetros de tipo em tipos struct são carregados através dos 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] usam o mesmo T da struct.Stack[int], Stack[string]) é um tipo distinto.Stack[int]{} está pronto para uso.Relacionado: Estruturas de Dados Genéricas: Conjuntos, Filas, Mapas - contêineres reutilizáveis
Restrições podem exigir métodos, não apenas uniões 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 deve implementar String() string.implements.T são permitidas porque estão na restrição.Relacionado: Parâmetros de Tipo e Interfaces de Restrição - restrições de método
comparableConstrua uma tabela de frequência com chave 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 e a Restrição comparable - regras para chaves de mapa
A declaração de variável curta escolhe a instanciação.
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: Estruturas de Dados Genéricas: Conjuntos, Filas, Mapas - contêineres com múltiplos parâmetros
~Aceite tipos nomeados com base em seu tipo subjacente.
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 inclui Celsius e Fahrenheit porque seu tipo subjacente é float64.~, apenas o tipo literal float64 corresponderia.Relacionado: Parâmetros de Tipo e Interfaces de Restrição - profundidade do operador
~
Tipos de união listam os 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)))
}| constrói uma união dentro de uma restrição de interface.Relacionado: Parâmetros de Tipo e Interfaces de Restrição - limites de união
Procure por helpers genéricos na biblioteca padrão antes de cópias 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 e maps são APIs genéricas por padrão no Go 1.21+.Relacionado: Algoritmos Genéricos: Pacotes slices, maps & cmp - catálogo da biblioteca padrão
Versões do Stack: Esta página foi escrita para Go 1.26.x (GC padrão Green Tea, go fix modernizers - verifique o patch na compilação), chi (última versão - verifique na compilação), gin (última versão - verifique na compilação), echo (última versão - verifique na compilação), google.golang.org/grpc (última versão - verifique na compilação), sigs.k8s.io/controller-runtime (última versão - verifique na compilação), kubebuilder (última versão - verifique na compilação), tinygo (última versão - verifique os alvos de placa na compilação), wazero (última versão - verifique na compilação) e golangci-lint (última versão - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026