泛型就是在编码中,涉及类型的定义可以不指定具体的类型,
编译器根据使用时的上下文来生成相应类型的定义。
比如:
func Compare(a, b T) bool {
return a == b
}
Compare(1, 1)
Compare("hello", "world")
在使用时,泛型展开为:
func Compare(a, b int) bool {
return a == b
}
func Compare(a, b string) bool {
return a == b
}
软件开发过程主要由编码 + 编译 + 运行组成。
泛型的加入可以提升编码效率,减少复制粘贴。
如果是只做必要的展开,运行效率应该不会受到影响。
但是,由于编译时面临的环境变得复杂,编译时间是肯定会提升一些,但这个提升必须在合理范围。而且,泛型的展开可能会导致编译产生的二进制文件大小增加。
PS: Java 采用类型擦除的策略实现泛型。
方案
func Keys[K comparable, V any](m map[K]V) []K {
r := make([]K, 0, len(m))
for k := range m {
r = append(r, k)
}
return r
}
评价
Golang 之父 Rob 表示 Go 核心团队目前也缺乏相关经验,为了保证稳定,1.18 的标准库暂时不要使用泛型。
后续
2021-11-13
Markjour:Go 泛型的最新动态2021-11-22
脑子进煎鱼了:泛型是双刃剑?Go1.18 编译会慢近 20%2021-11-24
脑子进煎鱼了:Go 新语法挺丑?最新的泛型类型约束介绍2022-02-07
脑子进煎鱼了:Go 泛型变更:约束太丑了,先移动到 x/exp 做实验性功能
参考资料与拓展阅读
- Go 语言之父:不要在 Go 1.18 标准库中使用泛型
- 酷壳(CoolShell.cn), GO 编程模式:泛型编程
- 知乎, Ian Lance Taylor:Go 泛型使用的一般准则