1、泛型
泛型是一种独立于所使用的特定类型的编写代码的方法。使用泛型可以编写出适用于一组类型中的任何一种的函数和类型。
2、泛型的语法
Go 语言不是主流的面向对象,泛型支持上也有所区别,如Java一切皆为对象,只要确定对象泛型即可统一的泛型模式。Go的每种类型都有区别,可简单分为两类,
- 类型泛型:切片泛型、哈希泛型、结构体泛型、基础类型泛型等;
- 函数泛型:函数泛型、方法泛型等。
另外泛型语法不是主流的<>
尖括号,而使用的[]
中括号,这不重要,思路都是相似的
- 类型泛型,风格基本一致,使用
type
定义别名,名称后面紧跟泛型定义,然后是基础类型。
- 函数泛型,语法也比较类似,函数名称后面紧跟泛型定义
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"
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
| type Stack[T any] struct { items []T }
func (s *Stack[T]) Push(item T) { s.items = append(s.items, item) }
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
,可以存储任意类型的元素。通过 Push
和 Pop
方法,我们可以操作栈中的元素。
reference