泛型的基本语法
Go 1.18 引入泛型,用类型参数(方括号)和类型约束(接口 + 类型集)编写通用代码:
// 泛型函数:交换两个变量
func Swap[T any](a, b *T) {
*a, *b = *b, *a
}
// 泛型类型:栈
type Stack[T any] []T
func (s *Stack[T]) Push(v T) { *s = append(*s, v) }
内置约束 any(任意类型)和 comparable(可比较类型);自定义约束用类型集:
type Number interface {
int | int64 | float64 // 类型集:只接受这些类型
}
func Add[T Number](a, b T) T { return a + b }
Add(3, 5) // OK
Add(3.14, 2.71) // OK
主要应用场景
1. 集合操作
func Filter[T any](s []T, f func(T) bool) []T {
var result []T
for _, v := range s {
if f(v) { result = append(result, v) }
}
return result
}
func Map[T, U any](s []T, f func(T) U) []U {
result := make([]U, len(s))
for i, v := range s { result[i] = f(v) }
return result
}
even := Filter([]int{1, 2, 3, 4, 5}, func(n int) bool { return n%2 == 0 })
squares := Map([]int{1, 2, 3}, func(n int) int { return n * n })
2. 通用数据结构
type Cache[K comparable, V any] struct {
data map[K]V
}
func (c *Cache[K, V]) Get(key K) (V, bool) {
v, ok := c.data[key]
return v, ok
}
3. 泛型排序(需要约束支持比较)
func SortSlice[T interface{ ~int | ~float64 | ~string }](s []T) {
sort.Slice(s, func(i, j int) bool { return s[i] < s[j] })
}
注意:Go 泛型目前没有 < 运算符约束,想对任意可比较类型排序需要自定义约束或用 cmp.Ordered(Go 1.21+):
import "cmp"
func SortAny[T cmp.Ordered](s []T) { sort.Slice(s, func(i, j int) bool { return s[i] < s[j] }) }
泛型 vs interface{}(反射)
// 传统方式:interface{} + 类型断言,运行期才检查,性能差
func PrintAll(vals []interface{}) { ... }
// 泛型:编译期类型检查,无反射开销
func PrintAll[T any](vals []T) { ... }
泛型的性能接近手写特化代码(编译器按类型参数实例化),同时保留静态类型安全。
注意事项与最佳实践
- 优先用于:多类型容器、通用算法(过滤/映射/排序)、通用数据结构;
- 避免滥用:单一类型、简单场景用泛型只会增加阅读负担;
- 编译时间:泛型会略微增加编译时间(约 15–18%),Go 1.23+ 有改善;
- 约束用最小化:约束越宽越好用,能用 comparable 就别自定义更严的约束;
- 工具链:需要 Go ≥ 1.18,IDE 支持(GoLand 2022.1+ / VSCode 新版)。
总结
泛型是 Go 1.18 以来最大的语言能力升级:编译期类型安全 + 复用 + 高性能。集合操作、通用数据结构、算法模板是它的主战场;配合 Go 1.21 的 cmp.Ordered、slices/maps 标准包,日常写泛型代码已经非常顺手。



