Golang 速成 | 泛型
Golang 在 1.18 版本引入了泛型(Generics),这是一种允许你编写能够处理多种类型的代码的特性,而无需牺牲类型安全性和性能。泛型通过类型参数来实现,类型参数使函数和数据结构可以在多种类型上操作。以下是 Go 泛型的基本介绍:
基本语法
在 Go 中,你可以使用类型参数来定义泛型函数和泛型类型。类型参数使用方括号 []
包围,并在函数名或类型名之后紧跟。
Go |
---|
| // 泛型函数
func Print[T any](s []T) {
for _, v := range s {
fmt.Println(v)
}
}
// 泛型类型
type List[T any] struct {
elements []T
}
func (l *List[T]) Add(element T) {
l.elements = append(l.elements, element)
}
|
类型约束
Go 中的泛型允许你对类型参数进行约束,以限制可以传递给类型参数的类型。最基本的约束是 any
,它表示可以是任何类型。你也可以使用接口作为约束。
Go |
---|
| type Number interface {
int | int32 | int64 | float32 | float64
}
func Sum[T Number](a, b T) T {
return a + b
}
|
使用示例
以下是一个使用泛型的简单示例,展示了如何创建泛型函数和类型,并如何使用它们。
Go |
---|
| package main
import "fmt"
// 泛型函数
func Print[T any](s []T) {
for _, v := range s {
fmt.Println(v)
}
}
// 泛型类型
type List[T any] struct {
elements []T
}
func (l *List[T]) Add(element T) {
l.elements = append(l.elements, element)
}
func main() {
// 使用泛型函数
// 此处编译器可以根据传递的参数自动推断出 T 的类型
// 所以不用写为Print[[]int]([]int{1, 2, 3, 4})
Print([]int{1, 2, 3, 4})
Print([]string{"a", "b", "c"})
// 使用泛型类型
// List[int] 表示创建了泛型类型 List 的一个实例,其中类型参数 T 被替换为 int。
// List[int] 代表一个整型列表。
// List[int]{} 部分初始化了一个空的 List[int] 实例。
intList := List[int]{}
intList.Add(1)
intList.Add(2)
fmt.Println(intList.elements)
stringList := List[string]{}
stringList.Add("hello")
stringList.Add("world")
fmt.Println(stringList.elements)
}
|
泛型优点
- 代码复用:通过泛型,可以编写更通用的代码,而不需要为每种类型重复实现相同的逻辑。
- 类型安全:泛型提供了编译时的类型检查,避免了运行时类型错误。
- 性能:Go的泛型实现不会引入额外的性能开销,保持了Go语言高效的运行性能。
总之,Go引入泛型为开发者提供了更强大的工具来编写高效、可重用且类型安全的代码。通过泛型,开发者可以在保持代码清晰简洁的同时,提高代码的灵活性和可维护性。