go 泛型

go 泛型

1. 类型参数(Type parameters)

Go语言的泛型(Generic)叫做类型参数。泛型可以让我们代码适应不同类型的参数。

泛型函数

声明语法

// 声明一个带有泛型的函数
// T 指类型参数,就是一个参数,代表类型
// Constraint 是对类型参数T的约束,限制T的取值, 可以是int、string、any等类型,any可以是任意类型的意思
// s 是要打印的参数
func name[T {Constraint}](s T) {}

函数名和函数参数列表之间插入了一组方括号,来表示类型参数。跟函数参数一样,我们需要为每一个类型参数指定「类型」,这种类型的类型Go语言称之为约束。

示例

// 打印函数
func print[T any](s ...T) {
    for _, i := range s {
        fmt.Println(i)
    }
}

T表是切片成员的类型,但T的实际类型在定义print()的时候是不确定的,需要在调用该函数的时候指明。也就是说,我们在调用print()函数的时候需要额外传入一个特殊参数来指定T的具体类型。这种特殊的参数就叫类型参数。

使用泛型函数

func main() {
    // 约束为int类型
    print[int](1, 3, 4) 
    
    // 约束为string类型
    print[string]("derek", "阿瓦达啃大瓜", "奇摩鸡")
    
    // 任意类型
    print[any](1, "wo")
    
    // 任意类型,与any一样
    print[interface{}](1, "wo")
    
    // 不指定约束类型,则输入的数据类型必须为同一种类型
    print(1, 3, 4)
}

指定出参类型

// 指定返回参数的类型是T
func add[T any](a, b T) T {
    return a + b
}

// 也可以返回指针
func addV2[T any](a T) *T {
    return &a 
}

func main() {
    // 约束为int类型
    add[int](1, 3, 4) 
    
    // 约束为string类型
    add[string]("derek", "阿瓦达啃大瓜")  
}

// 结果输出:
// 8
// derek阿瓦达啃大瓜

泛型类型

// 定义一个泛型的数组
type Nums[T any] []T

// 定义一个泛型的map, map的K比较特殊,必须使用comparable来约束, 否则不生效
type Map[K comparable, V any] map[K]V

2. 内置约束 comparable

泛型参数一般都可以进行运算操作,但有两个符号是特殊的,就是:== 和 !=。 如果参数需要使用这两个作比较,则一定要使用comparable。

// 比较两个参数t、v是否相等
func Comp[T comparable](s []T, v T) int {
    for i, t := range s {
        if t == v {
            return i
        }
    }
    return 0
}

如果把上述的comparable改为any,则会报错:

invalid operation: t == v (type parameter T is not comparable with ==)

map数据的key有需要使用comparable,否则也会报错

3.自定义约束 (Constraint)

泛型的Constraint,可以使用any、int、string、comparable都可以,还可以定义一个interface来定义约束

// Addable 泛型操作
type Addable interface {
    // 约束类型
    ~int | float32 | ~float64 | string
}

func add[T Addable](a, b T) T {
    return a + b
}

上述的"~"符号不是必须的,但加上"~"的话,系统会兼容基类参数类型。例如,这里定义了一个类型Int

type Int int

int就是Int的基类类型,如果是这时候Addable的是~int,则Int会在其约束范围内,否则不在约束范围内。

并集约束

取约束类型的并集,intfloat32都是约束

type Addable interface {
    int | float32 
}

交集约束

type Stringer interface {
    String() string
}

type Addable interface {
    int
    Stringer
}

这种情况下,Addable约束的类型,必须是int类型,且这个类型实现 Stringer 接口。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容