go 泛型

作者: GUIN蚂蚁 | 来源:发表于2022-06-30 13:44 被阅读0次

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 接口。

相关文章

  • go 泛型

    go 泛型 1. 类型参数(Type parameters) Go语言的泛型(Generic)叫做类型参数。泛型可...

  • 夯实 Java 基础1 - 泛型的使用与原理

    Java 泛型为我们写安全易读的通用程序提供了便利,Go 也将在 2.0 引入泛型。下面首先介绍 Java 泛型的...

  • Golang学习笔记---“泛型”的实现

    Golang学习笔记---“泛型”的实现 大家都知道,go语言中是没有泛型的,但是我们可以通过空接口的方式来实现泛...

  • Go语言 泛型

    本篇文章转载自 在go中使用"泛型" 在进入泛型的话题之前, 首先实现对int 数组切片的冒泡排序: 如你所见, ...

  • go泛型体验

    背景 有了泛型可以做到复用,比如sort,filter,map,reduce等常用方法,这里举个ch的例子我们写g...

  • Go 泛型初体验

    在 Go1.17 中,千呼万唤的泛型终于出来了,但又没有完全出来。在 Go1.17 的发布文档中,并没有提到泛型,...

  • go1.18探索 -- 泛型

    go1.18终于发布了,据说支持了泛型,今天让我来一探究竟。 安装 执行如下命令 确认安装完成 泛型讲解 先看个问...

  • 泛型 & 注解 & Log4J日志组件

    掌握的知识 : 基本用法、泛型擦除、泛型类/泛型方法/泛型接口、泛型关键字、反射泛型(案例) 泛型 概述 : 泛型...

  • go基本语法

    一、总结 1、Go没有对象,没有继承多台,没有泛型,没有try/catch2、Go有接口,函数式编程,csp并发模...

  • 【泛型】通配符与嵌套

    上一篇 【泛型】泛型的作用与定义 1 泛型分类 泛型可以分成泛型类、泛型方法和泛型接口 1.1 泛型类 一个泛型类...

网友评论

      本文标题:go 泛型

      本文链接:https://www.haomeiwen.com/subject/ihmfbrtx.html