**泛型是为了解决执行逻辑与类型无关的问题**,这类问题不关心给出的类型是什么,只需要完成对应的操作就足够。golang 中的泛型与java概念相似,但是并不完善,定义时需要规定类型范围 定义了一个相加函数,输入必须是int 或者 float32 ```golang func Sum[T int | float32](a, b T) T { return a + b } //调用有2种方式 // 1.类型推断 Sum(1, 2) // 2.指定类型 Sum[int](1, 2) ``` ## 一、泛型结构 + 切片 ```golang //定义 type GenericSlice[T int | string] []T //使用 GenericSlice[int]{1, 2, 3} ``` + map ```golang //定义 type GenericMap[K comparable, V int | string | byte] map[K]V //使用 gmap1 := GenericMap[int, string]{1: "hello world"} gmap2 := make(GenericMap[string, byte], 0) ``` + struct ```golang //定义 type GenericStruct[T int | string] struct { Name string Id T } //使用 GenericStruct[int]{ Name: "jack", Id: 1024, } GenericStruct[string]{ Name: "Mike", Id: "1024", } ``` + 泛型切片形参 ```golang type Company[T int | string, S int | string] struct { Name string Id T Stuff []S } Company[int, []int]{ Name: "lili", Id: 1, Stuff: []int{1}, } ``` + 泛型接口 ```golang type SayAble[T int | string] interface { Say() T } type Person[T int | string] struct { msg T } func (p Person[T]) Say() T { return p.msg } func main() { //定义SayAble(接口类型),然后初始化为Person,类似java向上造型 var s SayAble[string] s = Person[string]{"hello world"} fmt.Println(s.Say()) } ``` ## 二、类型集 ```golang type SignedInt interface { int8 | int16 | int | int32 | int64 } type UnSignedInt interface { uint8 | uint16 | uint32 | uint64 } //并集 type Integer interface { SignedInt | UnSignedInt } ``` ```golang type SignedInt interface { int8 | int16 | int | int32 | int64 } type Integer interface { int8 | int16 | int | int32 | int64 | uint8 | uint16 | uint | uint32 | uint64 } //交集 type Number interface { SignedInt Int } ``` ## 三、数据结构 + 队列 ```golang type Queue[T any] []T func (q *Queue[T]) Push(e T) { *q = append(*q, e) } func (q *Queue[T]) Pop(e T) (_ T) { if q.Size() > 0 { res := q.Peek() *q = (*q)[1:] return res } return } func (q *Queue[T]) Peek() (_ T) { if q.Size() > 0 { return (*q)[0] } return } func (q *Queue[T]) Size() int { return len(*q) } ``` + 堆 堆是一种特殊的数据结构,它可以在O(1)的时间内判断最大或最小值,所以它对元素有一个要求,那就是必须是可以排序的类型,但内置的可排序类型只有数字和字符串,并且go的泛型约束不允许存在带方法的接口,所以在堆的初始化时,需要传入一个自定义的比较器,比较器由使用者提供,比较器也必须使用泛型,如下最小堆实现(数组实现最小堆有元素下标公示) ```golang type Comparator[T any] func(a, b T) int type BinaryHeap[T any] struct { //数组容器 s []T //比较器 c Comparator[T] } ```