当前位置:网站首页>go泛型使用方法
go泛型使用方法
2022-08-03 09:18:00 【m0_67394230】
golang泛型使用方法
1. 泛型是什么
泛型生命周期只在编译期,旨在为程序员生成代码,减少重复代码的编写
在比较两个数的大小时,没有泛型的时候,仅仅只是传入类型不一样,我们就要再写一份一模一样的函数,如果有了泛型就可以减少这类代码
// int
func GetMaxNumInt(a, b int) int {
if a > b {
return a
}return b
}
// int8
func GetMaxNumInt8(a, b int8) int8 {
if a > b {
return a
}return b
}
2. 泛型的简单使用
2.1. 泛型示例
需要go版本大于等于1.18
我们先改造一下上面的示例,只需要在函数后用
中括号
声明T可能出现的类型,中间用符号"|"
分隔// 使用泛型
func GetMaxNum[T int | int8](a, b T) T {
if a > b {
return a
}return b
}
2.2. 自定义泛型类型
如果类型太多了怎么办呢?这时候我们就可以自定义泛型类型
// 像声明接口一样声明
type MyInt interface {
int | int8 | int16 | int32 | int64
}// T的类型为声明的MyInt
func GetMaxNum[T MyInt](a, b T) T {
if a > b {
return a
}return b
}
2.3. 调用带泛型的函数
如何调用这个带有泛型的函数呢?
var a int = 10
var b int = 20// 方法1,正常调用,编译器会自动推断出传入类型是int
GetMaxNum(a, b)// 方法2,显式告诉函数传入的类型是int
GetMaxNum[int](a, b)
3. 自定义泛型类型的语法
在2.2小节中我们可以看到一个泛型的简单自定义类型,本节将会详细描述泛型自定义类型的语法
3.1. 内置的泛型类型any和comparable
- any: 表示go里面所有的内置基本类型,等价于
interface{}
- comparable: 表示go里面所有内置的可比较类型:
int、uint、float、bool、struct、指针
等一切可以比较的类型
3.2. 声明一个自定义类型
跟声明接口一样,使用
type x interface{}
关键字来声明,不过里面的成员不再是方法,而是类型,类型之间用符号"|"
隔开type MyInt interface {
int | int8 | int16 | int32 | int64
}成员类型支持go中所有的基本类型
type MyT interface {
int | float32 | bool | chan int | map[int]int | [10]int | []int | struct{} | *http.Client
}
3.3. 泛型中的"~"符号是什么
符号
"~"
都是与类型一起出现的,用来表示支持该类型的衍生类型// int8的衍生类型
type int8A int8
type int8B = int8// 不仅支持int8, 还支持int8的衍生类型int8A和int8B
type MyInt interface {
~int8
}
4. 泛型的进阶使用
4.1. 泛型与结构体
创建一个带有泛型的结构体
User
,提供两个获取age
和name
的方法注意:
只有在结构体上声明了泛型,结构体方法中才可以使用泛型type AgeT interface {
int8 | int16
}type NameE interface {
string
}type User[T AgeT, E NameE] struct {
age T
name E
}// 获取age
func (u *User[T, E]) GetAge() T {
return u.age
}// 获取name
func (u *User[T, E]) GetName() E {
return u.name
}我们可以通过声明结构体对象时,声明泛型的类型来使用带有泛型的结构体
// 声明要使用的泛型的类型
var u User[int8, string]// 赋值
u.age = 18
u.name = “weiwei”// 调用方法
age := u.GetAge()
name := u.GetName()// 输出结果 18 weiwei
fmt.Println(age, name)
5. 泛型的限制或缺陷
5.1 无法直接和switch配合使用
将泛型和
switch
配合使用时,无法通过编译func GetT any T {
var t Tswitch T { case int: t = 18 } return t
}
只能先将泛型赋值给
interface
才可以和switch
配合使用func GetT any T {
var t Tvar ti interface{} = &t switch v := ti.(type) { case *int: *v = 18 } return t
}
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦
边栏推荐
猜你喜欢
随机推荐
多线程下的单例模式
php中去重二维数组
命令行加载特效 【cli-spinner.js】 实用教程
深度学习之 10 卷积神经网络2
Rabbit and Falcon are all covered, Go lang1.18 introductory and refined tutorial, from Bai Ding to Hongru, the whole platform (Sublime 4) Go lang development environment to build EP00
好用的插件
dflow入门2——Slices
行业 SaaS 微服务稳定性保障实战
MySQL_关于JSON数据的查询
WinCheck Script
Cartesi 2022 年 7 月回顾
Exception: Dataset not found.解决办法
【快手面试】Word2vect生成的向量,为什么可以计算相似度,相似度有什么意义?
ClickHouse删除数据之delete问题详解
慢 SQL 分析与优化
【字节面试】word2vector输出多少个类别
What are pseudo-classes and pseudo-elements?The difference between pseudo-classes and pseudo-elements
cmd(命令行)操作或连接mysql数据库,以及创建数据库与表
阿里云·短信发送
机器学习(公式推导与代码实现)--sklearn机器学习库