Go泛型编程实战从类型约束到泛型数据结构的完整指南
文章导语
Go 1.18引入了期待已久的泛型。两年多来,泛型已从"新特性"变为日常开发的标配。本文从类型约束到泛型数据结构,覆盖泛型在实际项目中的核心应用。
一、类型约束定义
go
// 内置约束
func Max[T constraints.Ordered](a, b T) T {
if a > b { return a }
return b
}
// 自定义约束
type Number interface {
~int | ~int32 | ~int64 | ~float32 | ~float64
}
func Sum[T Number](nums []T) T {
var total T
for _, n := range nums {
total += n
}
return total
}
二、泛型数据结构
go
// 泛型Stack
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, bool) {
if len(s.items) == 0 {
var zero T
return zero, false
}
item := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return item, true
}
// 泛型Set
type Set[T comparable] map[T]struct{}
func NewSet[T comparable]() Set[T] { return make(Set[T]) }
func (s Set[T]) Add(item T) { s[item] = struct{}{} }
func (s Set[T]) Contains(item T) bool { _, ok := s[item]; return ok }
三、实战:泛型Repository
go
type Repository[T any, ID comparable] interface {
FindByID(id ID) (T, error)
Save(entity T) error
Delete(id ID) error
}
四、全文总结
- 类型约束定义泛型参数的行为边界
- ~T匹配底层类型为T的所有命名类型
- 泛型数据结构减少类型转换代码
- 避免过度抽象:只在确实需要多类型支持时用泛型
参考文献
- Go Blog - An Introduction To Generics
- Go泛型设计提案
- Go 1.18 Release Notes