泛型(在 Go 1.18 中加入)让你可以通过类型参数编写适用于多种类型的函数和类型,同时保持编译时的类型安全。它消除了以前的权衡——要么为每种类型复制代码,要么使用 interface{} 而失去安全性。
泛型解决的问题
go
{ ... }
{ ... }
{} { ... }
// T is a type parameter constrained to be "ordered" (comparable with < >)
func Max[T constraints.Ordered](a, b T) T {
if a > b {
return a
}
return b
}
Max(3, 5) // T inferred as int → 5
Max(2.5, 1.1) // T inferred as float64 → 2.5
Max("a", "b") // T inferred as string → "b"
[T constraints.Ordered] 声明了一个类型参数 T,具有一个约束(允许哪些类型)。编译器从参数中推断 T —— 一个实现适用于多种类型,完全类型安全。
// a constraint is an interface listing allowed types or required methods
type Number interface {
~int | ~int64 | ~float64 // the | union means "any of these"
}
func Sum[T Number](nums []T) T {
var total T
for _, n := range nums {
total += n // safe — T is constrained to numeric types
}
return total
}
Sum([]int{1, 2, 3}) // 6
Sum([]float64{1.5, 2.5}) // 4.0
// built-in constraints:
any // any type (alias for interface{})
comparable // types usable with == (for map keys, etc.)
// golang.org/x/exp/constraints: Ordered, Integer, Float, etc.
约束定义了对类型参数有效的操作(~ 表示"底层类型为此的任何类型")。
// a generic stack that works for any type
type Stack[T any] struct {
items []T
}
func (s *Stack[T]) Push(item T) { s.items = append(s.items, item) }
func (s *Stack[T]) Pop() T {
item := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return item
}
intStack := Stack[int]{} // a stack of ints
strStack := Stack[string]{} // a stack of strings — same code
✓ Generic data structures (stacks, trees, sets), utility functions over collections
(Map, Filter, Reduce), type-safe containers
✗ Don't overuse — if interfaces or a concrete type work simply, prefer them.
Go's philosophy still favors simplicity; generics are a tool, not a default.
泛型是 Go 的一项重大的、期盼已久的补充(1.18),解决了一个真实的痛点:在此之前,为多种类型编写可复用代码迫使你要么为每种类型复制代码(冗长、难以维护),要么使用 interface{}(失去编译时类型安全,需要运行时断言)。
泛型让你可以一次性编写类型安全、可复用的函数和数据结构(容器、Map/Filter/Reduce 等集合工具),编译器强制执行正确性并推断类型。
理解类型参数、约束(包括 any、comparable 和联合/~ 语法)以及泛型类型,随着生态系统的采纳变得越来越重要。
同样重要的是 Go 的理念——泛型是真正复用的工具,而非默认选项 —— 过度使用泛型会违背 Go 的简洁哲学。
这是一个当前的、经常讨论的话题,反映了对现代 Go 的理解。