泛型
约 2 分钟阅读
Golang 泛型
- 类型参数
T any- 任意类型T int | int8- 其中之一T ~int- 允许衍生类型 - 例如type Age int
- 参考
- proposeLinkgo.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md类型参数 · - 任意类型 · - 其中之一 · - 允许衍生类型 - 例如 · 参考 · propose · Tutorial: Getting started with generics · 目前不好使用 new(T), 增加一个类型进行限制笔记:泛型
- Tutorial: Getting started with genericsLinkgo.dev/doc/tutorial/generics类型参数 · - 任意类型 · - 其中之一 · - 允许衍生类型 - 例如 · 参考 · propose · Tutorial: Getting started with generics · 目前不好使用 new(T), 增加一个类型进行限制笔记:泛型
- 目前不好使用 new(T), 增加一个类型进行限制
- method 不支持类型参数 - No parameterized methodsLinkgo.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md类型参数 · - 任意类型 · - 其中之一 · - 允许衍生类型 - 例如 · 参考 · propose · Tutorial: Getting started with generics · 目前不好使用 new(T), 增加一个类型进行限制笔记:泛型
- type 参数不支持 assert - 可以考虑
_,ok := any(v).(int)
- golang.org/x/exp/slices - #45955GitHub Issuegolang/go#45955
- lightweight anonymous function syntax - #21498GitHub Issuegolang/go#21498
- 使用 struct 字段作为一个类型 #48522GitHub Issuegolang/go#48522
FAQ
new(T)
目前该方法无法使用 stackoverflow.com/questions/71440697
- 直接限定不方便传参数,因为 struct 不一定实现 interface,
*struct才实现 interface
type Setter[T any] interface {
SetIndex(n int)
*T
}
func setIndex[T any, PT Setter[T]](items []int) (o []PT) {
for _, v := range items {
m := PT(new(T))
m.SetIndex(v)
o = append(o, m)
}
return
}
// 限定 接口 直接写也可以
func setIndex[T any, PT interface {
SetIndex(n int)
*T
}](items []int) (o []PT) {
for _, v := range items {
m := PT(new(T))
m.SetIndex(v)
o = append(o, m)
}
return
}func setIndex[M interface {
SetIndex(n int)
}](items []int) (o []M) {
for _, v := range items {
// NPE
m := *new(M)
m.SetIndex(v)
o = append(o, m)
}
return
}
type A struct {
Index int
}
func (s *A) SetIndex(v int) {
s.Index = v
}
func TestSetIndex(t *testing.T) {
// 会出现 NPE
fmt.Println(setIndex[*A]([]int{1, 2, 3, 4}))
}method must have no type parameters
- func 支持类型参数
- method 不支持类型参数
- 只能使用 struct 上的类型参数
- No parameterized methodsLinkgo.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md类型参数 · - 任意类型 · - 其中之一 · - 允许衍生类型 - 例如 · 参考 · propose · Tutorial: Getting started with generics · 目前不好使用 new(T), 增加一个类型进行限制笔记:泛型
type A struct{}
// method 不支持 类型参数
func (v A)Map[T any](f func(A)T)T{
return f(v)
}
// func 支持 类型参数
func Map[IN any, OUT any](s IN, f func(IN) OUT) (o OUT) {
return f(s)
}cannot use generic type without instantiation
type A[T any] struct {}
// 不可以
func(a A)Name(){}
// 可以
func(a A[T])Name(){}cannot use type assertion on type parameter value Xxx(variable of type T constrained by any)
type A[T any] struct {
Val T
}
func(a A[T])Name(){
// 不可以 - 因为 T 是具体类型
_,_=a.Val.(string)
// 可以
var v interface{} = a.Val
_, _ = v.(string)
// 可以
_, _ = (interface{})(a.Val).(string)
}- proposal: spec: generics: type switch on parametric types #45380GitHub Issuegolang/go#45380
关联信息
反向链接、本文链接的其他页面和外部资料。
反向链接
- Go Version笔记 · generic
Go-Release-Cycle · 一年两个版本 - 2 月,8 月 · bugfix backports 一个版本 · security backports 两个版本 · 参考 · golang/proposal · golang/go/projects/1
References
GitHub4 条
- golang/go#21498github.com/golang/go/issues/21498
- golang/go#45380github.com/golang/go/issues/45380
- golang/go#45955github.com/golang/go/issues/45955
- golang/go#48522github.com/golang/go/issues/48522
其他外链3 条
- go.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.mdgo.googlesource.com/proposal/+/refs/heads/master/design/43651-type-parameters.md
- go.dev/doc/tutorial/genericsgo.dev/doc/tutorial/generics
- stackoverflow.com/questions/71440697stackoverflow.com/questions/71440697