泛型
引言#
很久之前就听到过泛型的声音了,但是对于泛型我一直处于没碰到也懒得碰的状态,但是今天偶然看了一下 roadMap ,因此我打算开始碰一下我的泛型了,也就是基础学习一下,感觉没有需求不大会写的样子
泛型#
现在有个函数:
1 | func head(slice []int) (*int, bool) { |
以上代码可以看出特别简单
那么如果我们还要再实现一个 func head(slice []string) (*string, bool) {
呢?
这个时候就需要应用泛型了:
1 | func head[T any](slice []T) (*T, bool) { |
这个时候就可以既使用 int
又 使用string
了,我们直接将他定义成了 head[T any]
那么我们还可以这样写:
1 | // version 1 |
[ T int | string ]
表示 T 可以表示为 int , 或者 stringtype Header interface { int | string | ~int32 }
表示 Header 可以表示 int, string 以及底层用 int32 实现的类型 , 这种接口只能用于 泛型约束,不能写作:var h Header
注意这里的
~
这个表示底层用 Int32 实现的类型都可以用 T 接收使用1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22// such as :
type Header interface {
int | string | ~int32
}
func head[T Header](slice []T)(*T, bool){
if len(slice) > 0 {
return &slice[0] , true
}
return nil ,false
}
type MyInt int
type MyInt32 int32
func main() {
slice1 := []int{ 1, 2, 3}
slice2 := []int32{1,2,3}
head(slice1) // 这个是不通过的
head(slice2) // 这个是通过的
}
当我们想要获取这个函数的时候(不使用):
1 | f := head[string] |
Header
中也可以嵌入其他的接口和方法:
1 | // 这样子表示 参数 必须符合这些类型,并且还需要实现这个接口 |
但是不能嵌入带有方法的接口:
1 | // 下面是错误的示范: |
我们还可以实现泛型结构体
1 | type Box[T any ,S string] struct{ |
泛型是结构体和函数的一部分,所以当我们需要给变量赋值的时候就需要写成
var b Box[string]
或 f := head[string]
同时我们需要知道 var b Box[int]
和 var b Box[string]
是两种不同的类型,需要区分
同时也有泛型方法
1 | func (b Box[t]) Map() { |
接口泛型类型:
1 | type Getter[T any] interface{ |
总结#
其实个人觉得这个 泛型 非常鸡肋,至少我没看过多少人会使用这个泛型,哪怕使用也就是使用基本作用
类型推断#
Go语言的类型推断是指在声明变量时,编译器能够根据变量的初始化值自动推断出变量的类型,而无需显式地指定类型。这种特性使得Go语言的代码更加简洁和易读。
在变量初始化时进行类型推断
1
2x = 10 // 编译器会自动推断出x的类型为int
y = "Hello world!" // 编译器会自动推断出y的类型为string对函数返回值类型进行推断
1
2
3
4// 计算两个整数的和并返回
func add(a, b int) int {
return a + b
}复合类型的类型推断(struct)
1
2
3
4
5
6
7
8
9
10
11
12
13type Person struct {
Name string
Age int
}
p := Person{Name: "lipeilun", Age: 30} // 使用类型推断来创建Person对象
numbers := []int{1, 2, 3, 4, 5} // 使用类型推断来创建整数切片
// 使用类型推断来创建map对象
scores := map[string]int{
"lipeilun": 90,
"xiaobin": 85,
"windeal": 88,
}