以下是Go语言中关于 Go 泛型 - 泛型语法与示例 的详解,适合泛型入门学习和实际开发使用:
一、什么是泛型(Generics)?
泛型是一种支持"类型参数"的机制,可以让函数、类型等支持多种数据类型,提高代码复用性。
Go 从 1.18 版本开始正式支持泛型,主要体现在:
- • 泛型函数
- • 泛型类型(结构体、接口等)
- • 类型约束(constraints)
二、基本语法格式
泛型函数的声明
go
func PrintSlice[T any](s []T) {
for _, v := range s {
fmt.Println(v)
}
}
- •
T
是类型参数。 - •
[T any]
表示 T 可接受任意类型(any
是interface{}
的别名)。
泛型类型的声明
go
type Stack[T any] struct {
elements []T
}
func (s *Stack[T]) Push(v T) {
s.elements = append(s.elements, v)
}
func (s *Stack[T]) Pop() T {
l := len(s.elements)
val := s.elements[l-1]
s.elements = s.elements[:l-1]
return val
}
三、多个类型参数
go
func Compare[K comparable, V any](a map[K]V, b map[K]V) bool {
if len(a) != len(b) {
return false
}
for k, v := range a {
if b[k] != v {
return false
}
}
return true
}
- •
K comparable
限定K
必须是可比较类型(如用于 map key)。 - •
V any
无限制。
四、类型约束(Constraints)
使用接口作为约束
go
type Addable interface {
int | float64
}
func Sum[T Addable](a, b T) T {
return a + b
}
- • 类型集
int | float64
表示 T 可以是int
或float64
。 - •
Addable
是一个"约束接口"。
五、泛型实战示例
1. 泛型排序函数
css
func Min[T constraints.Ordered](a, b T) T {
if a < b {
return a
}
return b
}
- •
constraints.Ordered
是标准库提供的类型约束,表示支持< <= >= >
的类型。
2. 泛型 Map 函数(函数式编程)
go
func Map[T any, R any](list []T, f func(T) R) []R {
var result []R
for _, v := range list {
result = append(result, f(v))
}
return result
}
使用:
go
squares := Map([]int{1, 2, 3}, func(x int) int { return x * x })
fmt.Println(squares) // [1 4 9]
六、类型推断
Go 支持自动类型推断:
c
PrintSlice([]string{"a", "b", "c"})
也可以显式指定类型参数:
c
PrintSlice[string]([]string{"a", "b"})
七、标准库中的泛型支持(Go 1.18+)
Go 1.18+ 在 golang.org/x/exp/constraints
提供了常用的类型约束:
css
import "golang.org/x/exp/constraints"
func Max[T constraints.Ordered](a, b T) T {
if a > b {
return a
}
return b
}
八、使用建议
建议 | 说明 |
---|---|
✅ 用于数据结构通用化 | 如 Stack、Queue、Map 等 |
✅ 用于通用算法封装 | 如排序、筛选、映射、聚合 |
⚠ 避免过度使用泛型 | 不如接口清晰时不必用泛型 |
✅ 配合类型约束 | 提高类型安全性与可读性 |
九、小结
- • 泛型让 Go 支持了更高层次的抽象与复用,不再需要写多版本函数。
- • 与接口并用,可构建健壮、通用的框架组件。
- • 使用时注意性能与可读性的权衡。