go语言的泛型
2023-08-05 本文已影响0人
鸿雁长飞光不度
- 啥时候泛型有用?
- 当使用语言定义的容器类型时
- 通用目的的数据结构
- 啥时候泛型无用?
- 不要使用泛型替换接口
- 当方法的实现不同时,不要使用泛型
如果您发现自己多次编写完全相同的代码,其中副本之间的唯一区别是代码使用不同的类型,请考虑是否可以使用 类型参数。 另一种说法是,在注意到要多次编写完全相同的代码之前,应避免使用类型参数。
// 定义一个Page就可以了
type Page[T interface{}] struct {
Token string
Data []T
}
func ListGoods(page uint64, size uint64) Page[Goods] {
var result = Page[Goods]{
Token: "123456",
}
result.Data = []Goods{
{
ID: 1,
Name: "apple",
},
{
ID: 2,
Name: "banana",
},
}
return result
}
func ListUser(page uint64, size uint64) Page[User] {
var result = Page[User]{
Token: "123456",
}
result.Data = []User{
{
ID: 1,
Name: "zhangsan",
},
{
ID: 2,
Name: "lisi",
},
}
return result
}
队列处理
// 这里类型约束使用了空接口,代表的意思是所有类型都可以用来实例化泛型类型 Queue[T] (关于接口在后半部分会详细介绍)
type Queue[T interface{}] struct {
elements []T
}
// 将数据放入队列尾部
func (q *Queue[T]) Put(value T) {
q.elements = append(q.elements, value)
}
// 从队列头部取出并从头部删除对应数据
func (q *Queue[T]) Pop() (T, bool) {
var value T
if len(q.elements) == 0 {
return value, true
}
value = q.elements[0]
q.elements = q.elements[1:]
return value, len(q.elements) == 0
}
// 队列大小
func (q Queue[T]) Size() int {
return len(q.elements)
}
// 泛型类型
type Node struct {
value int
next *Node
}
type NodeF[T any] struct {
head *NodeF[T]
value T
}
// Ordered 是类型约束名称
type Ordered interface {
float64 | int // 或者的关系
}
type Ordered2 interface {
comparable
error // and的关系
}
// 这个泛型类型化约束不能用在传统的函数参数上
//func min(a ,b Ordered) {
//
//}
// 泛型函数
func min[T Ordered](x, y T) T {
if x < y {
return x
}
return y
}
// 泛型类型方法,这个是支持的
func (l *NodeF[T]) Value() T {
return l.value
}
// comparable可以这样用
func I15(K interface{ comparable }) {
}
// 泛型方法,这个是不支持的
// func (l *NodeF[T]) Len([V any]) int {
//
// }
type Tree[T any] struct {
Left *Tree[T]
Right *Tree[T]
V T
}
// 不恰当,slice和map是完全不同的类型,只是取值的方式相同,不适合用泛型强制合在一款
func Index[T map[int]string | []string](m T, k int) string {
return m[k]
}
type Client struct {
}
type Query[T any] struct {
client *Client
}
func NewQuery[T any](c *Client) *Query[T] {
return &Query[T]{
client: c,
}
}
func (q Query[T]) All(ctx context.Context) ([]T, error) {
return nil, nil
}