13-泛型简解

1、泛型

泛型是一种独立于所使用的特定类型的编写代码的方法。使用泛型可以编写出适用于一组类型中的任何一种的函数和类型。

2、泛型的语法

Go 语言不是主流的面向对象,泛型支持上也有所区别,如Java一切皆为对象,只要确定对象泛型即可统一的泛型模式。Go的每种类型都有区别,可简单分为两类,

  • 类型泛型:切片泛型、哈希泛型、结构体泛型、基础类型泛型等;
  • 函数泛型:函数泛型、方法泛型等。

另外泛型语法不是主流的<>尖括号,而使用的[]中括号,这不重要,思路都是相似的

  • 类型泛型,风格基本一致,使用type定义别名,名称后面紧跟泛型定义,然后是基础类型。
1
type MyGen[T any] int
  • 函数泛型,语法也比较类似,函数名称后面紧跟泛型定义
1
2
3
func MyFun[T any](x T, n int) {
...
}

2.1 泛型函数

在 Go 泛型中,我们可以定义泛型函数,其中的某些类型可以是泛型的。以下是一个简单的泛型函数的例子:

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

import "fmt"

// PrintSlice 打印切片的泛型函数
func PrintSlice[T any](s []T) {
for _, v := range s {
fmt.Printf("%v ", v)
}
fmt.Println()
}

func main() {
intSlice := []int{1, 2, 3, 4, 5}
stringSlice := []string{"apple", "banana", "orange"}

PrintSlice(intSlice)
PrintSlice(stringSlice)
}

在这个例子中,我们定义了一个名为 “PrintSlice” 的泛型函数,它接受一个类型为 “T” 的切片参数 “s”。在调用这个函数时,我们可以将 “T” 替换为任何数据类型。

2.2、泛型类型

除了泛型函数,Go 泛型还支持定义泛型类型。以下是一个泛型栈的简单实现:

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
35
// Stack 泛型栈的定义
type Stack[T any] struct {
items []T
}

// Push 将元素推入栈
func (s *Stack[T]) Push(item T) {
s.items = append(s.items, item)
}

// Pop 从栈中弹出元素
func (s *Stack[T]) Pop() T {
if len(s.items) == 0 {
panic("stack is empty")
}
item := s.items[len(s.items)-1]
s.items = s.items[:len(s.items)-1]
return item
}

func main() {
intStack := Stack[int]{}
stringStack := Stack[string]{}

intStack.Push(1)
intStack.Push(2)
intStack.Push(3)

stringStack.Push("apple")
stringStack.Push("banana")
stringStack.Push("orange")

fmt.Println("Int Stack Pop:", intStack.Pop())
fmt.Println("String Stack Pop:", stringStack.Pop())
}

在这个例子中,我们定义了一个泛型栈 Stack,可以存储任意类型的元素。通过 PushPop 方法,我们可以操作栈中的元素。

reference


13-泛型简解
https://flepeng.github.io/021-Go-31-Go-基础-13-泛型简解/
作者
Lepeng
发布于
2024年12月2日
许可协议