V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
yuancoder
V2EX  ›  Go 编程语言

Golang 的泛型能干什么

  •  
  •   yuancoder · 2023-09-03 11:01:08 +08:00 · 3119 次点击
    这是一个创建于 447 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Golang 在 1.18 版本支持了泛型, 在工作中还没有真正用过, 这几天研究了一下,脑子里最先想到的使用场景就是集合类型的处理。

    常用的集合处理函数 map, redude 等, 在别的语言中都是直接支持的,例如 PHP 中的 array_map, array_reduce

    但是 golang 之中只能使用 for 循环,现在有了泛型,让实现 map, reduce 变的简单了, 相比使用 interface,性能也更好。

    代码实现:

    func Map[T any, R any](ts []T, f func(T) R) []R {
    	nt := make([]R, 0, len(ts))
    	for _, t := range ts {
    		nt = append(nt, f(t))
    	}
    	return nt
    }
    
    func Reduce[T any](ts []T, f func(T, T) T, init T) T {
    	t := init
    	for _, tt := range ts {
    		t = f(t, tt)
    	}
    	return t
    }
    

    使用

    type Person struct {
        ID   int
        Name string
    }
    
    personList := []Person{
        { 1,"zhangsan"},
        { 2,"lisi"},
    }
    
    names := Map(personList, func(p Person) string { return p.Name })
    fmt.Println(names) // [zhangsan lisi]
    
    nums := []int{1,2,3,4}
    total := Reduce(nums, func(a, b int) int {
        return a+b
    }, 0)
    fmt.Println(total) // 10
    

    除了 map, reduce 还有其他的函数也可以使用泛型实现。

    我自己写了一个包: https://github.com/lyuangg/mr

    实现了:map, reduce, Contains, ToMap, Filter, Diff, Intersect, Unique, Merge 等函数。

    13 条回复    2023-09-12 11:27:12 +08:00
    chotow
        1
    chotow  
       2023-09-03 11:29:30 +08:00   ❤️ 4
    yuancoder
        2
    yuancoder  
    OP
       2023-09-03 11:47:14 +08:00
    @chotow #1 这个看起来挺全的
    Nasei
        3
    Nasei  
       2023-09-03 11:52:33 +08:00   ❤️ 2
    性能可能比 interface 好,但其实比自己直接实现要慢
    fzdwx
        4
    fzdwx  
       2023-09-03 12:19:47 +08:00   ❤️ 1
    Contextualist
        5
    Contextualist  
       2023-09-03 13:35:45 +08:00   ❤️ 7
    当然是用来实现邪道三元运算符:

    func tern[T any](cond bool, a T, b T) T {
       if cond {
          return a
       }
       return b
    }

    var x, y int
    x = tern(true, 42, 1)
    *tern(false, &x, &y) = 42
    hsfzxjy
        6
    hsfzxjy  
       2023-09-03 13:56:31 +08:00 via Android   ❤️ 1
    yuancoder
        7
    yuancoder  
    OP
       2023-09-03 15:50:16 +08:00
    @Contextualist #5 好代码
    Aloento
        8
    Aloento  
       2023-09-03 16:47:54 +08:00
    Go 的泛型实际很残废
    wangdk23411
        9
    wangdk23411  
       2023-09-03 19:00:41 +08:00
    @Contextualist 好思路
    bruce0
        10
    bruce0  
       2023-09-04 09:09:19 +08:00   ❤️ 1
    @hsfzxjy
    @Aloento

    刚出来的时候, 我也看过一篇文章, 详细分析了 go 泛型的实现. 确实残废. 而且不支持 方法 泛型

    瞎搞什么混合泛型, 用 `stenciling` 拉低了性能, 还不如 和 C++ 一样, 一个类型生成一段代码得了, 自己编译器都默认静态链接的, 说啥不在乎二进制体积, 到了泛型这里又开始在乎二进制体积了, 谜之操作. 真想减小二进制体积, 直接类型擦除 不是更小吗
    lysS
        11
    lysS  
       2023-09-04 09:50:31 +08:00
    用了泛型 any ,泛型就会有运行时的,并不会比单用 any 好
    voidmnwzp
        12
    voidmnwzp  
       2023-09-05 23:24:52 +08:00 via iPhone
    能不用尽量不用 这玩意影响编译速度
    beichenshao
        13
    beichenshao  
       2023-09-12 11:27:12 +08:00
    以前有 TypeScript 类型体操,以后 Go 也可以有类型体操了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2001 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:51 · PVG 08:51 · LAX 16:51 · JFK 19:51
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.