golang 研发学习之路之泛型

golang在1.18.x版本中,已经支持了泛型,从代码实现上看,整体在使用上比较简洁,但是如果结合面型对象思想做一些常见数据结构开发的时候,就会遇到各种各样的问题,该文将现以 队列 和 链表 两个数据结构还说明泛型的使用,相关代码我会放在github中。 github.com/xiezy1997/g...

如何在func中使用泛型?

  • 原始的func书写形式
go 复制代码
func Sum(a, b int) int {
	return a + b
}
  • 泛型的func书写形式
go 复制代码
func Sum[T int64 | float64](a, b T) T {
	return a + b
}

通过代码对比我们就可以看出,泛型是在funcName后面增加了一个[T],用来表示T的类型,那么我们在调用的时候,既可以显示告知方法类型,也可让方法自动识别类型是否匹配。

  • 调用方法
go 复制代码
fmt.Println(Sum[int64](a, b))
fmt.Println(Sum(c, d))

定义泛型的时候一定要枚举所有类型吗?

当然是不需要的啦,golang内置了一些约束,也可以自定义一些约束,以简化代码书写

  • 内置约束
内置约束 注意事项
any 实则interface{}
comparable 必须支持"=="方法
  • 自定义约束
go 复制代码
type Int interface {
	int | int8 | int16 | int32 | int64
}

func Sum[T Int](a, b T) T {
	return a + b
}

如何在struct中使用泛型?

go 复制代码
type LinkList[T any] struct {
	head *node[T]
	tail *node[T]
	cnt  int
}
type node[T any] struct {
	data T
	next *node[T]
}

其实我们将泛型应用在struct中也是十分简单的,只要我们在structName后面加上[T]即可在struct使用了,但是需要注意我们在创建这个struct对象的时候,需要显示指定这个T实际类型n := &node[int]{}

如何在接口中使用泛型?

go 复制代码
type IMath[T any] interface {
	Sum(a, b T) T
}

在interface中,我们也是只需要在interfaceName后面加上[T]即可使用泛型了

如何在常见数据结构中使用泛型呢?

其实我们只需要将struct、interface、func以及泛型整合到一起,即可实现在数据结构中使用泛型,具体可以看 github.com/xiezy1997/g...,此处仅放一个方法作为demo

go 复制代码
// interface.go
type ILinkList[T any] interface {
	// Iterator 获取迭代器函数
	//  @param ctx
	//  @return func() (T, bool): data, isNull
	Iterator(ctx context.Context) func() (T, bool)
}

// linklist.go
type LinkList[T any] struct {
	head *node[T]
	tail *node[T]
	cnt  int
}
func (l *LinkList[T]) Iterator(ctx context.Context) func() (T, bool) {
	p := l.head // 此处使用闭包的特性,实现迭代器操作
	return func() (T, bool) {
		if p == nil {
			var t T // 这里不能直接返回nil,一旦T不是指针的话,返回nil会出现panic,所以此处需要先创建其变量再返回
			return t, true
		}
		data := p.data
		p = p.next
		return data, false
	}
}
func NewLinkList[T any]() ILinkList[T] {
	return &LinkList[T]{}
}

// types.go
type node[T any] struct {
	data T
	next *node[T]
}

func newNode[T any]() *node[T] {
	return &node[T]{}
}
相关推荐
梦想很大很大10 小时前
使用 Go + Gin + Fx 构建工程化后端服务模板(gin-app 实践)
前端·后端·go
lekami_兰14 小时前
MySQL 长事务:藏在业务里的性能 “隐形杀手”
数据库·mysql·go·长事务
却尘18 小时前
一篇小白也能看懂的 Go 字符串拼接 & Builder & cap 全家桶
后端·go
ん贤19 小时前
一次批量删除引发的死锁,最终我选择不加锁
数据库·安全·go·死锁
mtngt111 天前
AI DDD重构实践
go
Grassto3 天前
12 go.sum 是如何保证依赖安全的?校验机制源码解析
安全·golang·go·哈希算法·go module
Grassto5 天前
11 Go Module 缓存机制详解
开发语言·缓存·golang·go·go module
程序设计实验室6 天前
2025年的最后一天,分享我使用go语言开发的电子书转换工具网站
go
我的golang之路果然有问题6 天前
使用 Hugo + GitHub Pages + PaperMod 主题 + Obsidian 搭建开发博客
golang·go·github·博客·个人开发·个人博客·hugo
啊汉7 天前
古文观芷App搜索方案深度解析:打造极致性能的古文搜索引擎
go·软件随想