Parâmetros de Tipo e Interfaces de Restrição
Parâmetros de tipo são declarados em listas de colchetes, e interfaces de restrição definem quais tipos podem substituí-los usando métodos, tipos subjacentes (~T) e uniões (|).
Busque em todas as páginas da documentação
Parâmetros de tipo são declarados em listas de colchetes, e interfaces de restrição definem quais tipos podem substituí-los usando métodos, tipos subjacentes (~T) e uniões (|).
Parâmetros de tipo transformam tipos concretos em variáveis de tempo de compilação para funções e tipos nomeados.
Interfaces de restrição são as barreiras de segurança: elas listam operações e conjuntos de tipos permitidos.
O operador ~ corresponde a tipos nomeados pelo tipo subjacente; | une múltiplos tipos ou tipos subjacentes em uma restrição.
Tipos de restrição nomeados mantêm as APIs legíveis quando o mesmo limite aparece em muitas assinaturas.
Cartão de receita de referência rápida - pronto para copiar e colar.
// Restrição nomeada - reutilizável entre APIs
type Ordered interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 |
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
~float32 | ~float64 |
~string
}
func Clamp[T Ordered](v, lo, hi T) T {
if v < lo {
return lo
}
if v > hi {
return hi
}
return v
}Quando usar isso:
~byte).int | string é inválido para operações compartilhadas - projete com cuidado).package main
import (
"fmt"
"strconv"
)
// Restrição de método
type Stringable interface {
String() string
}
// Tipo subjacente + união
type Digit interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
type UserID int
func (id UserID) String() string {
return strconv.Itoa(int(id))
}
func FormatAll[T Stringable](items []T) string {
out := ""
for i, v := range items {
if i > 0 {
out += ", "
}
out += v.String()
}
return out
}
func Twice[T Digit](v T) T {
return v * 2
}
func main() {
ids := []UserID{1, 2, 3}
fmt.Println(FormatAll(ids))
fmt.Println(Twice(UserID(5)))
}O que isso demonstra:
v.String() dentro do corpo genérico.~int permite que UserID satisfaça Digit sem listar todos os tipos de int nomeados.Stringable vs Digit).func F[T any]()) ou tipos (type Stack[T any] struct{}).any.| Forma | Exemplo | Corresponde |
|---|---|---|
| Lista de métodos | interface { Read([]byte) (int, error) } | Tipos com método Read |
| Tipo subjacente | ~int | int, MyInt, qualquer tipo nomeado com int subjacente |
| Literal de tipo | int | Apenas o tipo literal int, não o nomeado MyInt |
| União | ~int | ~float64 | Ints e floats nomeados ou literais por regras de membro |
| Misto | interface { ~int; String() string } | int subjacente e método String() |
| Sintaxe | Significado |
|---|---|
[T any] | Parâmetro único, sem restrição |
[T, U comparable] | Dois parâmetros, restrições independentes |
[T Ordered, U any] | Mistura restrições personalizadas e pré-declaradas |
func (s *Set[T]) Add(v T) | Método usa T da struct, sem nova lista de parâmetros |
// Extrai restrições para nomes de nível de pacote para APIs públicas
type JSONMarshaler interface {
MarshalJSON() ([]byte, error)
}
func Encode[T JSONMarshaler](v T) ([]byte, error) {
return v.MarshalJSON()
}
// Embutindo restrições pré-declaradas
type Key interface {
comparable
fmt.Stringer
}<, o corpo não pode usar < em T.cmp.Ordered e cmp.Or da biblioteca padrão em vez de copiar grandes listas de união.int em vez de ~int - Tipos nomeados como type Celsius float64 não corresponderão apenas a float64. Correção: use ~float64 quando tipos nomeados devem se qualificar.int | string não pode usar + ou comparações compartilhadas além de == se não forem comparáveis juntas. Correção: restrinja a união ou divida as funções.comparable incorretamente - interface { comparable; []byte } é inválido porque slices não são comparáveis. Correção: liste apenas termos de tipo comparáveis.[T any, T comparable] é inválido. Correção: um nome por parâmetro na lista.| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
cmp.Ordered / restrições da biblioteca padrão | Auxiliares de ordenação e igualdade | Tipos de domínio específicos não ordenados |
Geração de código (go generate) | Muitos tipos, nenhuma sintaxe genérica na API | Pequeno número de auxiliares, equipe conhece genéricos |
interface{} / any + type switch | Formas verdadeiramente dinâmicas (JSON, plugins) | Caminhos críticos que precisam de tipagem estática |
| Funções separadas não genéricas | Apenas dois tipos concretos | Muitos tipos com lógica idêntica |
~T significa "qualquer tipo cujo tipo subjacente seja T."
Inclui tipos nomeados definidos como type MyInt int.
Sim com |, mas toda operação no corpo genérico deve ser válida para todos os membros da união.
Uniões amplas frequentemente falham nas verificações de compilação.
Exporte quando os chamadores precisarem nomeá-las para seus próprios genéricos.
Mantenha restrições internas não exportadas e estáveis.
É uma interface de restrição da biblioteca padrão listando tipos embutidos e subjacentes ordenados.
Prefira importar cmp em vez de copiar a união.
Sim - o embutimento de interface funciona como interfaces comuns.
Conjuntos de métodos se combinam de acordo com as regras de interface do Go.
any permite todos os tipos, mas não == a menos que você restrinja.
comparable permite operações de igualdade em tipos permitidos.
Tipos de interface não podem declarar parâmetros de tipo em Go.
Use funções genéricas ou structs genéricas em vez disso.
Leia a mensagem do compilador sobre qual operação falhou em qual argumento de tipo.
Reduza a união ou adicione métodos necessários à restrição.
Não - instanciações são em tempo de compilação.
A reflexão vê tipos instanciados concretos, não nomes de parâmetros.
Quando o mesmo limite aparece em três ou mais assinaturas ou documenta um conceito de domínio (por exemplo, NodeID).
Não - regras de satisfação implícita não são alteradas.
Restrições são interfaces usadas em tempo de compilação.
Não - apenas tipos genéricos carregam parâmetros para métodos.
Funções livres e tipos genéricos declaram parâmetros.
comparablecmp.OrderedVersões de 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 - verifique na compilação), gin (última - verifique na compilação), echo (última - verifique na compilação), google.golang.org/grpc (última - verifique na compilação), sigs.k8s.io/controller-runtime (última - verifique na compilação), kubebuilder (última - verifique na compilação), tinygo (última - verifique os alvos de placa na compilação), wazero (última - verifique na compilação), e golangci-lint (última - verifique o conjunto de linters na compilação).
Revisado por Chris St. John·Última atualização: 19 de jul. de 2026