Go语言 泛型
Go 1.18引入泛型特性,通过类型参数实现代码复用。主要特性包括:1)使用方括号声明类型参数;2)通过接口约束限制类型范围;3)支持可比较类型。泛型适用于通用数据结构(栈、队列)、算法复用(排序、搜索)等场景,能减少重复代码。示例展示了泛型函数Max和泛型结构体DynamicArray的实现,需要导入golang.org/x/exp/constraints实验包。泛型使Go在保持类型安全的同时提
·
Go语言在1.18版本中正式引入了泛型(Generics)特性。泛型允许你编写可以处理多种类型的代码,而无需为每种类型重复编写相同的逻辑。在Go中,泛型主要通过类型参数(type parameters)来实现。
一、核心概念
1.类型参数(Type Parameters) 用方括号 [] 声明泛型类型参数:
func PrintSlice[T any](s []T) {
for _, v := range s {
fmt.Println(v)
}
}
T any
:T
是类型参数,any
表示约束(任意类型)。
2.类型约束(Type Constraints) 限制可用的类型范围:
type Number interface {
int | float64
}
func Sum[T Number](s []T) T {
var sum T
for _, v := range s {
sum += v
}
return sum
}
int | float64
:T
只能是int
或float64
。
3.可比较类型(Comparable Types) 使用内置 comparable 约束支持 == 和 !=:
func FindIndex[T comparable](s []T, target T) int {
for i, v := range s {
if v == target {
return i
}
}
return -1
}
需要安装golang.org/x/exp/constraints模块。
go get golang.org/x/exp/constraints
二、关键语法
- 泛型函数:
func Swap[T any](a, b T) (T, T) {
return b, a
}
- 泛型类型:
type Stack[T any] struct {
items []T
}
func (s *Stack[T]) Push(item T) {
s.items = append(s.items, item)
}
- 接口约束:
type Stringer interface {
String() string
}
func ToString[T Stringer](v T) string {
return v.String()
}
三、使用场景
1.通用数据结构 (栈、队列、链表等)
type Queue[T any] struct {
items []T
}
func (q *Queue[T]) Enqueue(item T) {
q.items = append(q.items, item)
}
2.算法复用 (排序、搜索、比较等)
func Max[T constraints.Ordered](a, b T) T {
if a > b {
return a
}
return b
}
3.减少重复代码 避免为不同类型写相同逻辑的函数。
四、完整示例
package main
import (
"fmt"
"golang.org/x/exp/constraints"
)
// 泛型函数:求最大值
func Max[T constraints.Ordered](a, b T) T {
if a > b {
return a
}
return b
}
// 泛型类型:动态数组
type DynamicArray[T any] struct {
data []T
}
func (da *DynamicArray[T]) Append(item T) {
da.data = append(da.data, item)
}
func main() {
// 使用 Max 函数
fmt.Println(Max(3, 7)) // 7
fmt.Println(Max(2.8, 1.5)) // 2.8
// 使用 DynamicArray
arr := DynamicArray[int]{}
arr.Append(10)
arr.Append(20)
fmt.Println(arr.data) // [10 20]
}
需要导入实验性约束包:
go get golang.org/x/exp/constraints
核心功能解析:
1.定义泛型结构体 DynamicArray:
type DynamicArray[T any] struct {
data []T
}
- DynamicArray 是一个泛型结构体,其中 T any 表示它可以存储任何类型的元素。
- 结构体中有一个字段 data,它是一个切片(slice),可以动态地增长和收缩,用于存储数组的元素。
2.定义 Append 方法:
func (da *DynamicArray[T]) Append(item T) {
da.data = append(da.data, item)
}
- Append 方法用于向 DynamicArray 中添加一个元素。
- da *DynamicArray[T] 表示接收者是指向 DynamicArray 结构体的指针。
- item T 是要添加的元素,其类型与 DynamicArray 的泛型参数 T 一致。
- 方法内部调用 append 函数将新元素添加到 data 切片中。
3.主函数 main:
func main() {
// 使用 Max 函数
fmt.Println(Max(3, 7)) // 7
fmt.Println(Max(2.8, 1.5)) // 2.8
// 使用 DynamicArray
arr := DynamicArray[int]{}
arr.Append(10)
arr.Append(20)
fmt.Println(arr.data) // [10 20]
}
- 调用了 Max 函数两次,分别比较了两个整数和两个浮点数,输出了它们的最大值。
- 创建了一个 DynamicArray 的实例 arr,并指定了实例的类型为 int。这意味着 arr 只能存储整型数据。
更多推荐
所有评论(0)