golang泛型基本用法
作者:matrix 被围观: 19 次 发布时间:2025-05-31 分类:Golang | 无评论 »
Golang在1.18版本中就引入了泛型的支持,现在开发使用版本都是1.23,1.24 平时写的时候还是知之甚少~ 这几天又看到GOrm v1.30.0版本中也加入了泛型支持 不错不错 😆 📝
泛型声明
普通函数的泛型
func Print[T any](value T) {
fmt.Println(value)
}
T 即表示泛型,不确定的类型,调用的时候指定
any
表示对T的约束,这里即表示没有任何约束的特殊约束
结构体中的泛型
type Box[T any] struct {
value T
}
支持结构体的字段类型的泛型。
Box
是一个泛型结构体,其字段 value
的类型是 T
实例化时指定
// 举例:实例化 Box[int]
boxInt := Box[int]{value: 42}
fmt.Println("Box[int]:", boxInt.Value)
这里类型指定非必需,不指定类型时GO会自己完成参数类型推导
结构体方法中的泛型
允许使用结构体泛型
func (b *Box[T]) SetValue(value T) {
b.value = value
}
这里SetValue
是 Box[T]
的方法,它使用了结构体的泛型参数 T
注意:Golang不支持结构体方法中独立的泛型参数
// 错误:Go 不支持在方法中声明独立的泛型参数
func (b *Box[T]) SetValue[K any](key K) {
// ...
}
这里的K
就是独立的泛型参数,因为在结构体中没有声明就会报错
泛型约束
自定义约束
一般泛型类型的约束any
表示任意类型用的比较多,不过也可以自定义约束类型
比如自定义的类型约束 CType
: 仅允许 uint
、string
和 float64
和自定义类型 myint
type myint int32
type CType interface{
~uint | ~string | ~float64 | myint
}
~
表示近似约束(Approximation Constraint)(只有底层类型才允许这样声明),~string
意思是只要底层类型是string的都允许,这里~
的表达意思其实和nginx中的匹配规则异曲同工-
没有
~
表示准确约束,CType中的myint
意思是只允许myint类型,底层int类型都不行
使用时也可以简写省略interface 参考下面的[[### 其他高级用法]]
其他内置约束
除了自定义也有很多可用的其他内置约束。
comparable
约束:支持 ==,!=
操作符的类型
其他常用约束:golang.org/x/exp/constraints
函数约束
限制其必须实现指定方法,其实就是接口interface的约束
type Stringer interface {
String() string
}
func myprin2[T Stringer](value T) {
fmt.Println(value)
}
除了类型约束之外 还可以约束是否实现指定方法,这里即对T
约束 必需实现String() 方法
交集约束
还可以进行交集约束,也就是多个约束条件必须都满足。
type StringableSignedInteger interface {
~int | ~int8 | ~int16 | ~int32 | ~int64 //约束 底层int类型
String() string //约束 必须实现String方法
}
func myprin23[T StringableSignedInteger](value T) {
fmt.Println(value)
}
type myint int
func (m myint) String() string {
return fmt.Sprintf("%d", m)
}
func main(){
myprin23[myint](1)
myprin23(myint(1))
}
上面例子中的StringableSignedInteger约束:
底层类型必需为底层*int类型(~int | ~int8 | ~int16 | ~int32 | ~int64
),并且要实现String()方法
其他高级用法
避免创建interface
可以如下 简写,约束为:int | ~string
func myprin3[T interface{ int | ~string }](value T) {
fmt.Println(value)
}
func myprin33[T int | ~string](value T) {
fmt.Println(value)
}
参考:
https://taoshu.in/go/generics/design.html
https://github.com/sesopenko/genericpubsub