Golang泛型教程
点击阅读简单的Golang泛型教程
Golang泛型教程
Golang是一门比较年轻的编程语言,在经过长期的发展之后,其在各个领域都已经得到了广泛应用。Golang的1.17版本开始引入泛型特性的支持。
Golang泛型主要有以下几个方面的应用:
- 函数和方法的泛型声明
- 接口的泛型声明
- 结构体和嵌入的泛型
接下来,我们将会深入探究这些方面的内容,并且通过简单的示例代码来演示Golang泛型的用法。
函数和方法的泛型声明
在Golang 1.17之前,Golang的函数和方法中只支持使用具体类型进行声明,在函数内部也都只能使用特定类型的变量或参数。而引入泛型之后,Golang的函数和方法中就可以使用泛型类型进行声明了。
泛型函数
在函数中使用泛型类型进行声明的语法为:
1
2
3
func 函数名[T any](参数列表) 返回值类型 {
// 函数体
}
其中,T
代表任意类型,可以在函数内部用于声明变量或参数。
下面是一个示例代码,演示了如何在函数中使用泛型:
1
2
3
4
5
6
7
8
9
10
11
func Swap[T any](a, b *T) {
*a, *b = *b, *a
}
func main() {
// 使用泛型函数
a := 1
b := 2
Swap(&a, &b)
fmt.Println(a, b)
}
这段代码中,我们声明了一个名为Swap
的泛型函数,该函数接收两个指向任意类型的变量的指针,并且使用*
操作符进行变量内容的交换。在实际调用该函数的时候,我们传递了两个int
类型的指针,使得a
和b
的值进行了交换。
泛型方法
对于方法而言,我们同样可以使用泛型类型进行声明。在方法中使用泛型类型进行声明的语法为:
1
2
3
4
func (接收者类型) 方法名[T any](参数列表) 返回值类型 {
// 函数体
}
其中,T
代表任意类型,并且可以在方法内部用于声明变量或参数。
下面是一个示例代码,演示了如何在方法中使用泛型:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
type Stack[T any] []T
func (s *Stack[T]) Push(v T) {
*s = append(*s, v)
}
func (s *Stack[T]) Pop() T {
index := len(*s) - 1
res := (*s)[index]
*s = (*s)[:index]
return res
}
func main() {
// 使用泛型方法
var s Stack[int]
s.Push(1)
s.Push(2)
s.Push(3)
fmt.Println(s.Pop())
fmt.Println(s.Pop())
}
这段代码中,我们声明了一个名为Stack
的泛型类型,并且在其中声明了两个泛型方法Push
和Pop
。这两个方法都使用了T
作为自己的泛型类型,使得方法可以适用于任意类型。在实际使用的时候,我们通过Stack[int]
来声明一个类型为int
的栈,并且对其进行了相应的操作。
接口的泛型声明
在Golang 1.17后,我们还可以使用泛型类型来声明接口。在这种情况下,我们可以使用type
关键字来定义一个代表任意类型的泛型类型,并且在接口中使用该类型来进行声明。
下面是一个示例代码,演示了如何在接口中使用泛型:
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
34
type Container[T any] interface {
Get() T
Put(v T)
}
type Stack[T any] []T
func (s *Stack[T]) Push(v T) {
*s = append(*s, v)
}
func (s *Stack[T]) Pop() T {
index := len(*s) - 1
res := (*s)[index]
*s = (*s)[:index]
return res
}
func (s *Stack[T]) Get() T {
return s.Pop()
}
func (s *Stack[T]) Put(v T) {
s.Push(v)
}
func main() {
// 使用泛型接口
var c Container[int] = new(Stack[int])
c.Put(1)
c.Put(2)
fmt.Println(c.Get())
fmt.Println(c.Get())
}
这段代码中,我们声明了一个名为Container
的泛型接口,并且在其中声明了Get
和Put
两个方法,这两个方法都使用了T
作为自己的泛型类型。而在Stack
类型的实现中,我们同样实现了Get
和Put
方法,并且额外声明了一个方法Pop
,用于从栈中获取元素。在实际使用中,我们通过Container[int]
声明了一个类型为int
的容器,并且使用Stack[int]
实现了该容器。
结构体和嵌入的泛型
在Golang 1.17后,我们还可以在结构体和嵌入中使用泛型类型进行声明。这种情况下,我们可以使用与函数和方法类似的语法进行声明。
下面是一个示例代码,演示了如何在结构体和嵌入中使用泛型:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
type Pair[T any] struct {
first T
second T
}
type IntPair struct {
Pair[int]
}
func main() {
// 使用结构体和嵌入的泛型
p := IntPair{Pair[int]{1, 2}}
fmt.Println(p.first, p.second)
}
这段代码中,我们声明了一个名为Pair
的泛型结构体,并且定义了一个包含两个成员变量first
和second
的结构体。在IntPair
类型的定义中,我们嵌入了Pair[int]
,使得IntPair
类型包含了两个类型为int
的成员变量。在实际使用中,我们通过IntPair{Pair[int]{1, 2}}
来创建一个类型为IntPair
的变量p
,并且获取了其中的两个成员变量。
总结
到此为止,我们已经讲解了在Golang 1.17中泛型的主要应用场景,包括函数、方法、接口、结构体和嵌入。在实际开发中,我们可以使用这些泛型来提高程序的可扩展性和可重用性,从而让程序更加灵活和具有适应性。如果您还没有尝试过使用Golang中的泛型,那么不妨在接下来的代码中尝试一下吧!
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名 TinyZ Zzh (包含链接: https://tinyzzh.github.io ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。 如有任何疑问,请 与我联系 (tinyzzh815@gmail.com) 。
评论