前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >golang泛型基本用法

golang泛型基本用法

作者头像
HHTjim 部落格
发布于 2025-06-01 05:44:01
发布于 2025-06-01 05:44:01
9202
代码可运行
举报
文章被收录于专栏:HHTjim'S 部落格HHTjim'S 部落格
运行总次数:2
代码可运行

golang泛型基本用法

作者:matrix 被围观: 14 次 发布时间:2025-05-31 分类:Golang | 无评论 »

Golang在1.18版本中就引入了泛型的支持,现在开发使用版本都是1.23,1.24 平时写的时候还是知之甚少~ 这几天又看到GOrm v1.30.0版本中也加入了泛型支持 不错不错 😆 📝

泛型声明

普通函数的泛型
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func Print[T any](value T) {
    fmt.Println(value)
}

T 即表示泛型,不确定的类型,调用的时候指定

any 表示对T的约束,这里即表示没有任何约束的特殊约束

结构体中的泛型
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type Box[T any] struct {
    value T
}

支持结构体的字段类型的泛型。 Box 是一个泛型结构体,其字段 value 的类型是 T

实例化时指定
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 举例:实例化 Box[int]
boxInt := Box[int]{value: 42}
fmt.Println("Box[int]:", boxInt.Value)

这里类型指定非必需,不指定类型时go会自己完成参数类型推导

结构体方法中的泛型

允许使用结构体泛型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func (b *Box[T]) SetValue(value T) {
    b.value = value
}

这里SetValueBox[T] 的方法,它使用了结构体的泛型参数 T

注意:golang不支持结构体方法中独立的泛型参数

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 错误:Go 不支持在方法中声明独立的泛型参数
func (b *Box[T]) SetValue[K any](key K) {
    // ...
}

这里的K就是独立的泛型参数,因为在结构体中没有声明就会报错

泛型约束

自定义约束

一般泛型类型的约束any 表示任意类型用的比较多,不过也可以自定义约束类型

比如自定义的类型约束 CType: 仅允许 uintstringfloat64和自定义类型 myint

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type myint int32
type CType interface{
~uint | ~string | ~float64 | myint
}
  • ~ 表示近似约束(Approximation Constraint)(只有底层类型才允许这样声明),~string 意思是只要底层类型是string的都允许,这里~的表达意思其实和nginx中的匹配规则异曲同工
  • 没有~ 表示准确约束,CType中的myint 意思是只允许myint类型,底层int类型都不行

使用时也可以简写省略interface 参考下面的[[### 其他高级用法]]

其他内置约束

除了自定义也有很多可用的其他内置约束。

comparable 约束:支持 ==,!=操作符的类型

其他常用约束:golang.org/x/exp/constraints

函数约束

限制其必须实现指定方法,其实就是接口interface的约束

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type Stringer interface {
    String() string
}

func myprin2[T Stringer](value T) {
    fmt.Println(value)
}

除了类型约束之外 还可以约束是否实现指定方法,这里即对T约束 必需实现String() 方法

交集约束

还可以进行交集约束,也就是多个约束条件必须都满足。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
type StringableSignedInteger interface {
    ~int | ~int8 | ~int16 | ~int32 | ~int64 //约束 底层int类型
    String() string //约束 必须实现String方法
}

func myprin23[T StringableSignedInteger](value T) {
    fmt.Println(value)
}


type myint int
func (m myint) String() string {
    return fmt.Sprintf("%d", m)
}


func main(){
    myprin23[myint](1)
    myprin23(myint(1))
}

上面例子中的StringableSignedInteger约束: 底层类型必需为底层*int类型(~int | ~int8 | ~int16 | ~int32 | ~int64),并且要实现String()方法

其他高级用法

避免创建interface 可以如下 简写,约束为:int | ~string

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func myprin3[T interface{ int | ~string }](value T) {
    fmt.Println(value)
}


func myprin33[T int | ~string](value T) {
    fmt.Println(value)
}

参考:

https://taoshu.in/go/generics/design.html https://github.com/sesopenko/genericpubsub

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-05-31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
lodash源码分析之缓存方式的选择
本文为读 lodash 源码的第八篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
对角另一面
2018/01/22
1.1K0
lodash源码分析之List缓存
本文为读 lodash 源码的第七篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
对角另一面
2018/01/17
1.1K0
lodash源码分析之缓存方式的选择
每个人心里都有一团火,路过的人只看到烟。 ——《至爱梵高·星空之谜》 本文为读 lodash 源码的第八篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitbook也会同步仓库的更新,gitbook地址:pocket-lodash 前言 在《lodash源码分析之Hash缓存》和《lodash源码分析之List缓存》介绍了 lodash 的两种缓存方式,这两种缓存方式都实现了和 Map 一致的数据管理接口,其中 List 缓存只在不支持 Map 的环境中使用,那何时使用 H
对角另一面
2018/03/30
1.2K0
lodash源码分析之Hash缓存
本文为读 lodash 源码的第四篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
对角另一面
2018/01/17
1.1K0
lodash源码分析之Hash缓存
在那小小的梦的暖阁,我为你收藏起整个季节的烟雨。 ——洛夫《灵河》 本文为读 lodash 源码的第四篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitbook也会同步仓库的更新,gitbook地址:pocket-lodash 作用与用法 Hash 顾名思义,就是要有一个离散的序列,根据 key 来储取数据。而在 javascript 中,最适合的无疑是对象了。 Hash 在 lodash 的 .internal 文件夹中,作为内部文件来使用。lodash 会根据不同的数
对角另一面
2018/03/30
1.1K0
lodash源码分析之数组的差集
外部世界那些破旧与贫困的样子,可以使我内心世界得到平衡。 ——卡尔维诺《烟云》 本文为读 lodash 源码的第十七篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitbook也会同步仓库的更新,gitbook地址:pocket-lodash 作用与用法 baseDifference 可以用来获取指定数组与另一个数组的差集。 这个函数是内部函数,是后面实现其它比较函数的核心函数。 baseDifference 的方法签名如下: baseDifference(array, v
对角另一面
2018/03/30
2.4K0
lodash源码分析之compact中的遍历
对角另一面
2017/12/27
1.1K0
lodash源码分析之compact中的遍历
本文为读 lodash 源码的第三篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
对角另一面
2018/01/17
8840
lodash源码分析之自减的两种形式
本文为读 lodash 源码的第六篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
对角另一面
2018/01/17
7330
lodash源码分析之NaN不是NaN
本文为读 lodash 源码的第五篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
对角另一面
2018/01/17
1.9K0
lodash源码分析之获取数据类型
所有的悲伤,总会留下一丝欢乐的线索,所有的遗憾,总会留下一处完美的角落,我在冰峰的深海,寻找希望的缺口,却在惊醒时,瞥见绝美的阳光! ——几米 本文为读 lodash 源码的第十八篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash gitbook也会同步仓库的更新,gitbook地址:pocket-lodash 作用与用法 我们都知道,可以借用 Object 原型上的 toString 方法来获取数据的类型。 baseGetTag 利用的也是这一特性,其返回的结果如 [obj
对角另一面
2018/04/19
9180
读lodash源码之从slice看稀疏数组与密集数组
对角另一面
2017/12/27
1.2K0
lodash源码分析之baseFindIndex中的运算符优先级
本文为读 lodash 源码的第十篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
对角另一面
2018/02/05
7540
学习 lodash 源码整体架构,打造属于自己的函数式编程类库
这是 学习源码整体架构系列第三篇。整体架构这词语好像有点大,姑且就算是源码整体结构吧,主要就是学习是代码整体结构,不深究其他不是主线的具体函数的实现。文章学习的是打包整合后的代码,不是实际仓库中的拆分的代码。
ConardLi
2019/09/17
2.4K0
学习 lodash 源码整体架构,打造属于自己的函数式编程类库
lodash源码分析之chunk的尺与刀
以不正义开始的事情,必须用罪恶使它巩固。 ——莎士比亚《麦克白》 最近很多事似乎印证了这句话,一句谎言最后要用一百句谎言来圆谎。 本文为读 lodash 源码的第二篇,后续文章会更新到这个仓库
对角另一面
2017/12/27
8310
内功修炼之lodash—— clone&cloneDeep(一定有你遗漏的js基础知识)
本文实现方法都是看效果倒推实现方法,并进行一些拓展和思考,和源码无关。lodash这个库在这里更像一个题库,给我们刷题的
lhyt
2019/11/19
5.5K0
大厂面试:JavaScript各种源码解析
func 是要调用的函数,是由 context 调用,func 的指向 context,所以关注点在 context 指向
Javanx
2019/09/04
7400
vue源码中值得学习的方法
作者:chinamasters https://segmentfault.com/a/1190000025157159
桃翁
2020/10/23
7470
vue源码中值得学习的方法
lodash源码分析之_.range
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/j_bleach/article/details/72824386
j_bleach
2019/07/02
7350
哈希表
哈希表,又叫散列表,是数据结构的一种。 散列表用途很广泛,比如一个电话薄,每一个姓名对应一个电话号码。姓名与电话号码呈映射关系。假如要创建一个电话薄,可以使用 JavaScript 对象来实现。
多云转晴
2019/10/30
9350
哈希表
相关推荐
lodash源码分析之缓存方式的选择
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档