owenqing 联系🪐

Go1.18 泛型

一、泛型

什么是泛型?泛型是类型参数。通俗的说就是给静态语言一个动态的机会,使用泛型写出来的是模板代码,最终的类型会在编译时确定。
注:泛型的本质是一种模板技术

golang 在最新的 1.18 版本中正式发布了泛型
https://golang.google.cn/doc/go1.18

二、泛型函数

函数泛型只需要在函数名后的"中括号"中申明类型即可,这一点与 scala 语言类似。
与常见的 Java 等语言不同的是 go 的泛型也是有类型的。这种类型是对泛型的一种约束。
这种约束可以来源自基础类型 comparable, any 也可以来自 interface
注:
- comparable 约束,使得传入的参数必须能进行 == 与 != 操作
- any 约束,可以是任意类型
- interface 约束其实有三种
1. 如下面例子的可选类型
2. 方法约束(多态)
3. 1 与 2 共同作用

type Number interface {
    int | int32 | int64 | float32 | float64
}

func sum[T Number](a, b T) T {
    return a * b
}

func main() {
    // 调用时指明类型是可选的
    // 不写类型编译器会自动推导
    sum[int](1, 2) // int 类型
    sum(2.2, 2.3) // float 类型
    ...
}

Number 约束了 T 类型只能是 int, int32 int64 float32 float64 中的一个

三、泛型容器

List Map 是两种最为常见的容器,我们一般会对容器抽象出一些方法,如:

  • iterator
  • hasElement
  • ...

这里使用泛型避免了针对每一个类型的元素都去实现一遍容器的对应方法(逻辑相同,类型不一致...)

注:
- 泛型容器提供了容器的操作模板,里面可以装任意类型
- golang channel 也是相同的道理

type List[T any] []T

type Map[K comparable, T any] map[K]V

type Chan[T any] chan T

func main() {
    // 泛型 List
    listInt := List[int]{1, 2, 3}
    listFloat := List[float54]{1.2, 2.2, 2.3}

    // 泛型 Map
    mapStrAny := Map[string, string]{
        "1": "cat",
        "2": "dog",
    }

    // 泛型 Chan
    cInt := make(Chan[int], 1)
    cInt <- 123
    cStr := make(Chan[string], 1)
    cStr <- "hello world"
    ...
}

四、泛型结构体

结构体与上述容器一样也可以定义泛型参数。
Struct 的泛型参数比较特殊的是可以将其带入到成员方法中...

type Collection[T any] struct {
	collect []T
}

func NewCollection[T any](list []T) *Collection[T] {
	return &Collection[T]{
		collect: list,
	}
}

func (s *Collection[T]) Map(trans func(e T) T) *Collection[T] {
	var list []T
	for _, e := range s.collect {
		list = append(list, trans(e))
	}
	return &Collection[T]{
		collect: list,
	}
}

func (s *Collection[T]) Result() []T {
	return s.collect
}

func main() {
        result := NewCollection([]int{1, 2, 3}).Map(func(e int) int { return e * 3 }).Result()
	fmt.Println(result)

}
posted @   owenqing  阅读(751)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
点击右上角即可分享
微信分享提示