Golang泛型学习笔记

什么是泛型?

泛型程序设计(generic programming)是程序设计语言的一种风格或范式。泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。

Golang泛型Demo

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package main

import (
	"fmt"
)
func main() {
	strs := []string{"aaa", "vdfe", "djmerui"}
	is := []int{1, 2, 3}
	printArray(strs)
	printAnyArray(strs)
	printComparableArray(strs)
	printArray(is)
	printAnyArray(is)
	printComparableArray(is)
}
// T 形式类型  string int  指定的实际类型
func printArray[T string | int](arr []T) {
	for _, a := range arr {
		fmt.Println(a)
	}
}
// 内置的泛型类型 any  任意类型  
func printAnyArray[T any](arr []T) {
	for _, a := range arr {
		fmt.Println(a)
	}
}
// 内置的泛型类型  comparable 可比较的类型
func printComparableArray[T comparable](arr []T) {
	for _, a := range arr {
		fmt.Println(a)
	}
}

泛型的作用

泛型减少重复代码并提高类型安全性

在下面情最的时候非常适合使用泛型:当你需要针对不同类型书写同样的逻辑,使用泛型来简化代码是最好的

泛型类型

只定义一个类型就能代表你想要的所有类型

Demo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package main
import "fmt"
func main() {
	type MySlice[T int | float64] []T
	var s1 MySlice[int] = []int{1, 2, 3, 4}
	var s2 MySlice[float64] = []float64{1.11, 2.22, 3.33, 4.44}
	fmt.Print(s1, "  ")
	fmt.Printf("%T", s1)
	fmt.Println()
	fmt.Print(s2, "  ")
	fmt.Printf("%T", s2)
	fmt.Println()
	type MyMap[KEY int | string, VALUE any] map[KEY]VALUE
	var mp MyMap[string, int] = map[string]int{
		"go":   5,
		"java": 6,
	}
	fmt.Print(mp, "   ")
	fmt.Printf("%T", mp)
}

运行结果
[1 2 3 4]  main.MySlice[int]
[1.11 2.22 3.33 4.44]  main.MySlice[float64]
map[go:5 java:6]   main.MyMap[string,int]

泛型map

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
type TMap[K string | int, V any] map[K]V

func main() {
	p := make(TMap[string, any])
	p["1"] = 456
	p["2"] = 45.6
	p["3"] = "45.6"
	for s := range p {
		r := reflect.TypeOf(p[s])
		fmt.Println(p[s], r.String())
	}
}

//运行结果:
456 int
45.6 float64
45.6 string

泛型函数

泛型函数

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

func Add[T int | float64 | string](t1, t2 T) T {
	return t1 + t2
}
func main() {
	fmt.Println(Add("S", "3"))
	fmt.Println(Add(1, 2))
	fmt.Println(Add(1.5, 2.6))
	fmt.Println(Add[string]("de", "fr"))
	fmt.Println(Add[int](2, 4))
}
运行结果
S3
3
4.1
defr
6

泛型方法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
package main

import "fmt"

type MySlice[T int | float64 | string] []T

func (s MySlice[T]) GetMax() T {
	var max T
	for _, v := range s {
		if v > max {
			max = v
		}
	}
	return max
}

func main() {
	var s1 MySlice[int] = []int{1, 22, 3, 4, 5, 6, 6}
	fmt.Println(s1.GetMax())
	var s2 MySlice[string] = []string{"hrty", "ger", "cre"}
	fmt.Println(s2.GetMax())
}

运行结果
22
hrty

泛型的使用

Go的泛型(或者或类型形参)目前可使用在了个地方

  1. 泛型类型 -类型定义中带类型形参的类型

  2. 泛型rceiver -泛型类型的receiver

  3. 泛型西数 -带类型形参的函数

自定义泛型

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import "fmt"

type int888 int8

type MyInt interface {
   ~int8 | int | int32 | int64 | float64
}

func GetMacNum[T MyInt](t1, t2 T) T {
   if t1 > t2 {
   	return t1
   }
   return t2
}
func main() {
   var a int888 = 2
   var b int888 = 3
   fmt.Println(GetMacNum(a, b))
}