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

go 泛型以后会支持特例化吗

  •  
  •   kkhaike ·
    kkhaike · 116 天前 · 2417 次点击
    这是一个创建于 116 天前的主题,其中的信息可能已经有所发展或是发生改变。

    RT ,网上搜不到有相关计划的言论和类似的问题。。

    最近有个工具库想改成泛型。发现没有特例化根本写不出来。连 isEmpty 这种都写不出来。(samber/lo 的 IsEmpty 只能作用于 comparable )。

    其他语言泛型之所以这么花很大的原因就是特例化。。

    我在想如果函数本身特例化不好实现。以后会不会方法实现类似于

    func IsEmpty[T any](x T) bool {
      switchtype T {
      case comparable:
        var zero T
        return x == zero
      case xxx:
        其他实现,每个 case 块做到 build 隔离,
        要不 如果是 uncomparable 类型,就无法构建 == 了
      case YYY:
      }
    }
    
    14 条回复    2022-08-07 20:06:12 +08:00
    bosskwei
        1
    bosskwei  
       116 天前
    你这是动态语言的写法,像 py 一样 isinstance 。编译型语言应该是 func IsEmpty[T comparable](x T) bool 这样写
    weirdte
        2
    weirdte  
       116 天前 via iPhone
    @bosskwei 特化,rust 和 cpp 支持的
    tairan2006
        3
    tairan2006  
       116 天前
    你这个也不是不能搞,你写一个接口把 case 对应的接口全写进去,然后 T 用这个接口做约束…就是用起来很烦。

    或者你还是用 switch t.(type)这种非泛型思路写吧。
    Trim21
        4
    Trim21  
       116 天前 via Android
    很可能不会支持…

    go 的博客里有这么一句话

    “write Go programs by writing code, not by defining types”
    cubecube
        5
    cubecube  
       116 天前
    @Trim21 哈哈,我倒是感觉以后没准会,毕竟 JAVA 的基础类型泛型特例化都要来
    lance6716
        6
    lance6716  
       116 天前 via Android
    如果自己根据类型不同,写成 IsEmpty1 ,IsEmpty2 ,有什么不方便使用的呢?

    这里不方便的点,就是编译时难处理的点
    dragonsunmoon
        7
    dragonsunmoon  
       116 天前
    唉...go 的泛型还是一个残废呀
    泛型与 go 的语言设计思想就是背道而驰的, 即便弄出个泛型, 也是这种夹生饭.
    24bit
        8
    24bit  
       115 天前
    短期不用想
    zizon
        9
    zizon  
       115 天前
    你有没想过限定 T 为某个 type interface { IsEmpty bool() }?
    lysS
        10
    lysS  
       115 天前   ❤️ 1
    可以把基础类型定义为自定义类型,然后通过“泛型接口”

    type CanEmptyT interface {
    ~int | ~string | ~[]byte
    Empty() bool
    }


    type SliceByte []byte

    func (sb SliceByte) Empty() bool {
    if sb == nil || *(*int)(unsafe.Add(unsafe.Pointer(&sb), 8 /*WORD*/)) == 0 {
    return true
    } else {
    return false
    }
    }

    func DoSomething[T CanEmptyT](v T) {
    if v.Empty() {
    fmt.Println("null")
    } else {
    fmt.Println(v)
    }
    }

    func main() {
    var a SliceByte
    DoSomething(a)

    var b []byte
    DoSomething[SliceByte](b)
    }


    这种泛型与接口结合的方法我觉得可以使 go 达到“完备”;但是目前有性能损失: https://www.infoq.cn/article/xprmcl5qbf6yvdroajyn
    Aloento
        11
    Aloento  
       115 天前
    在 golang 里面搞这些也不太现实,毕竟 golang 这种语言的目标就是一把梭快速开发
    Manweill
        12
    Manweill  
       115 天前
    来.NET 吧,你想到的都有
    bruce0
        13
    bruce0  
       115 天前
    @lysS 这篇文章真的干, 看了半个多小时 好多知识还是没能消化😭
    wewewefff
        14
    wewewefff  
       114 天前
    GO 是最简单的方式,完成最好的效果
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3553 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 52ms · UTC 05:03 · PVG 13:03 · LAX 21:03 · JFK 00:03
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.