One minute
Golang_generic
preface
前一段时间golang的泛型再次被提及, 看了相关的proposal之后, 一直没空写, 最近终于得空, 写一波
特点
泛型 基于 type parameter 实现的, type parameter 通常用 []
圈起来, 如下使用:
func F[T any] (p T) { .... } // T 就是 F 的 type parameter
type M[T any] []T // type parameter list 的定义
func F[T Contraint](p T) { .... } // 具有约束的泛型
与之相对的是, 常规的参数是 non-type parameter
, 两者最显著的区别就是 []
.
除了 type parameter, 频繁的词是 type argument
, 是运行泛型代码的时候的入参, 会替换掉 type parameter
.
约束可以理解成 对 泛型的行为定义, 但是相比于java, 缺乏了 extend 和 super, 通常用 interface 约束泛型, 比如:
// Stringify calls the String method on each element of s,
// and returns the results.
func Stringify[T Stringer](s []T) (ret []string) {
for _, v := range s {
ret = append(ret, v.String())
}
return ret
}
这里用 Stringer 约束了 T 的行为, 需要注意的是, T 的参数只能使用 约束提供的方法. 但是比较有意思的是, 复杂场景下, 可以用 具备泛型的 interface 作为 参数的 约束.
在类型推导上, 遵循三个步骤:
- non-type parameter 是否合法
- type-parameter 推演, 确定其他
- type-parameter 替换
- type-parameter 是否合法
整体的感觉, 还是偏向 interface + 参数推导 来做的, 相比于之前 contract 的思路, 还是更加容易接受些
缺点
-
举个例子,+ - < > = 这种算法表达式没有定义 interface, 目前社区讨论的是 借助 type list 的方式处理, 但是 只能解决基本类型,对于自定义的struct 还是无奈的, 没有比如 rust std:operaion 的各种类型, 但是一定程度上削弱了 泛型的表达能力
-
鸡肋: 引入了 any 替换 interface{}, 但是 any 没有任何功能
-
graph 的例子挺呕心的, 社区应该优化下. 能有个关联类型就好了, 得问问 (尝试优化下)
对比
java
https://juejin.im/post/6844904155316764685 得自己搞下了