package goSyntax import ( "fmt" "sync" ) func GenericDef() { // 一:泛型类型的定义 // 使用类型参数来定义类型 type mySlice[P int | string] []P // 泛型类型 mySlice[P] type myMap[K int | string, V float64 | float32] map[K]V type myList[T int | float64] struct { data []T l int max, min, avg T } // 二:声明泛型类型的变量 // 泛型类型的的实例化,得到了具体的 []int, []string _ = mySlice[int]{1, 2, 3, 4} _ = mySlice[string]{"one", "two", "three", "four"} // 注意:泛型不是那种类型都可以的意思,不是弱类型的概念 //_ = mySlice[int|string]{1, 2, "three", "four"} _ = myMap[string, float32]{ // map[string]float32 "go": 99.5, } _ = myList[int]{ data: []int{1, 2, 3}, max: 3, } // 三,测试数据的类型 fmt.Printf("%T\n", mySlice[int]{1, 2, 3, 4}) fmt.Printf("%T\n", mySlice[string]{"one", "two", "three", "four"}) fmt.Printf("%T\n", myMap[string, float32]{ // map[string]float32 "go": 99.5, }) fmt.Printf("%T\n", myList[int]{ data: []int{1, 2, 3}, max: 3, }) } func GenericExt() { // 一:类型约束为基础类型 // ~ type intSlice[P ~int] []P _ = intSlice[int]{} // 以int为基础类型的自定义类型 type myInt int type yourInt myInt _ = intSlice[myInt]{} _ = intSlice[yourInt]{} // Cannot use int32 as the type interface{ ~int } //_ = intSlice[int32]{} // 二,基于泛型类型,继续定义泛型类型 type mySlice[T int | string | float32 | float64] []T // mySlice[T] type floatSlice[T float32 | float64] mySlice[T] // type myStruct[T float32 | float64] struct { FieldA mySlice[T] } // 三:错误语法注意 // 类型即可是int也可是string //type myT[T int | string] T //type myT interface{ int | string } type T1[P *int,] []P type T2[P interface{ *int }] []P } // 一:定义泛型类型 type myList[T int | float64 | int32 | float32] struct { data []T max, min T m sync.Mutex } // 二:定义泛型类型的方法集 // 1, 添加元素,更新最大值最小值 // 泛型接收器, 泛型类型参数类型 func (l *myList[T]) Add(ele T) *myList[T] { // 加锁并发安全考虑 l.m.Lock() defer l.m.Unlock() // 更新 data l.data = append(l.data, ele) // 统计 min max if len(l.data) == 1 { l.max = ele l.min = ele } if ele > l.max { l.max = ele } if ele < l.min { l.min = ele } return l } // 2, 获取元素 func (l myList[T]) All() []T { return l.data } func (l myList[T]) Max() T { return l.max } func (l myList[T]) Min() T { return l.min } func GenericReceiver() { //l := myList[int]{} l := myList[float64]{} // 添加 l.Add(1.1).Add(3.3).Add(10.01) // 获取元素 fmt.Println(l.All()) fmt.Println(l.Max(), l.Min()) } type Queue[T int | string] struct { data []T } func (q *Queue[T]) Put(v ...T) *Queue[T] { q.data = append(q.data, v...) return q } func (q *Queue[T]) Pop() (T, bool) { var v T if len(q.data) == 0 { return v, true } v = q.data[0] q.data = q.data[1:] return v, len(q.data) == 0 } func (q Queue[T]) Size() int { return len(q.data) } // 泛型函数求和 func Sum[T int | string](ele ...T) T { var s T for _, v := range ele { s += v } func(n T) { }(s) return s } func GenericFunc() { // 显式指定类型,调用函数 fmt.Println(Sum[int](1, 2, 3)) fmt.Println(Sum[string]("ma", "shi", "bing")) } func GenericInference() { // 显式指定类型,调用函数 fmt.Println(Sum(1, 2, 3)) fmt.Println(Sum("ma", "shi", "bing")) } func GuessType[T int | string](ele ...T) T { var s T for _, v := range ele { s += v } func(n T) { }(s) return s } func TypeInference() { // fmt.Println(GuessType[int](1, 2, 3)) fmt.Println(GuessType[string]("Ma", "Shi", "Bing")) // 类型推断 fmt.Println(GuessType(1, 2, 3)) fmt.Println(GuessType("Ma", "Shi", "Bing")) // 全部指定 GuessType2[int, string](42, "Ma") // 指定前面部分 GuessType2[int](42, "Ma") // 指定后边部分 GuessType2(42, "Ma") // 合理 GuessType3(42, []int{}) // 不合理 //GuessType3(42, []string{}) } func GuessType2[K int | string, V float64 | string](p1 K, p2 V) { } func GuessType3[K int | string, V []K](p1 K, p2 V) { } // 泛型接口 generate interface type Data[T int | string] interface { Process(T) (T, error) Save() error } func GenerateInterface() { // JsonData 实现了 Data[string] DataOperate(JsonData{}) // NumberData 没有实现 Data[string] //DataOperate(NumberData{}) DataOperateInt(NumberData{}) } func DataOperate(p Data[string]) { } func DataOperateInt(p Data[int]) { } // Data[string] 相当于 //type Data interface { // Process(string) (string, error) // Save() error //} // 实现接口的类型 type JsonData struct{} func (JsonData) Process(string) (string, error) { return "", nil } func (JsonData) Save() error { return nil } type NumberData struct{} func (NumberData) Process(int) (int, error) { return 0, nil } func (NumberData) Save() error { return nil }