Go 1.18将移除用于泛型的constraints包
背景 Go官方团队在Go 1.18 Beta 1版本的标准库里因为泛型设计而引入了contraints
包。
文章图片
constraints
包里定义了Signed
,Unsigned
, Integer
, Float
, Complex
和Ordered
共6个interface类型,可以用于泛型里的类型约束(type constraint
)。
比如我们可以用constraints
包写出如下泛型代码:
// test.go
package main
?
import (
"constraints"
"fmt"
)
?
// return the min value
func min[T constraints.Ordered](a, b T) T {
fmt.Printf("%T ", a)
if a < b {
return a
}
return b
}
?
func main() {
minInt := min(1, 2)
fmt.Println(minInt)
?
minFloat := min(1.0, 2.0)
fmt.Println(minFloat)
?
minStr := min("a", "b")
fmt.Println(minStr)
}
函数
min
是一个泛型函数,接收2个参数,返回其中的较小者。类型参数
T
的类型约束contraints.Ordered
的定义如下:type Ordered interface {
Integer | Float | ~string
}
上面代码的执行结果为:
int 1
float64 1
string a
备注:如果对Go泛型和
constraints
包还不太了解的同学,可以翻看我之前写的一文读懂Go泛型设计和使用场景。现状 Go官方团队的技术负责人Russ Cox在2022.01.25提议将
constraints
包从Go标准库里移除,放到x/exp
项目下。Russ Cox给出的理由如下:There are still questions about the the constraints package. To start with, although many people are happy with the name, many are not. On top of that, it is unclear exactly which interfaces are important and should be present and which should be not. More generally, all the considerations that led us to move slices and maps to x/exp apply to constraints as well.该提议也同Go语言发明者Rob Pike, Robert Griesemer和Ian Lance Taylor做过讨论,得到了他们的同意。
【golang|重大变化(Go 1.18将移除用于泛型的constraints包)】We left constraints behind in the standard library because we believed it was fundamental to using generics, but in practice that hasn't proven to be the case. In particular, most code uses any or comparable. If those are the only common constraints, maybe we don't need the package. Or if constraints.Ordered is the only other commonly used constraint, maybe that should be a predeclared identifier next to any and comparable. The ability to abbreviate simple constraints let us remove constraints.Chan, constraints.Map, and constraints.Slice, which probably would have been commonly used, but they're gone.
Unlike other interfaces like, say, context.Context, there is no compatibility issue with having a constraint interface defined in multiple packages. The problems that happen with duplicate interfaces involve other types built using that type, such asfunc(context.Context)
vsfunc(othercontext.Context)
. But that cannot happen with constraints, because they can only appear as type parameters, and they are irrelevant to type equality for a particular substitution. So having x/exp/constraints and later having constraints does not cause any kind of migration problem at all, unlike what happened with context.
For all these reasons, it probably makes sense to move constraints to x/exp along with slices and maps for Go 1.18 and then revisit it in the Go 1.19 or maybe Go 1.20 cycle. (Realistically, we may not know much more for Go 1.19 than we do now.)
Discussed with @robpike, @griesemer, and @ianlancetaylor, who all agree.
其中Robert Griesemer和Ian Lance Taylor是Go泛型的设计者。
Russ Cox将这个提议在GitHub公布后,社区成员没有反对意见,因此在2022.02.03这个提议得到正式通过。
不过值得注意的是,2022.01.31发布的Go 1.18 Beta 2版本里还保留了
constraints
包,不建议大家再去使用。备注:
-
golang.org/x
下所有package的源码独立于Go源码的主干分支,也不在Go的二进制安装包里。如果需要使用golang.org/x
下的package,可以使用go get
来安装。
-
golang.org/x/exp
下的所有package都属于实验性质或者被废弃的package,不建议使用。
移除原因 支持泛型的Go 1.18 Beta 1版本发布以来,围绕着
constraints
包的争议很多。主要是以下因素,导致Russ Cox决定从Go标准库中移除
constraints
包。-
constraints
名字太长,代码写起来比较繁琐。
- 大多数泛型的代码只用到了
any
和comparable
这2个类型约束。constaints
包里只有constraints.Ordered
使用比较广泛,其它很少用。所以完全可以把Ordered
设计成和any
以及comparable
一样,都作为Go的预声明标识符,不用单独弄一个constraints
包。
总结 建议不要使用
constraints
包,毕竟Go 1.18正式版本会去掉。我写了2篇Go泛型入门的教程,欢迎大家参考
- 官方教程:Go泛型入门
- 一文读懂Go泛型设计和使用场景
好文推荐
- Go Quiz: Google工程师的Go语言面试题
- Go Quiz: 从Go面试题看slice的底层原理和注意事项
- Go Quiz: 从Go面试题搞懂slice range遍历的坑
- Go Quiz: 从Go面试题看channel的注意事项
- Go Quiz: 从Go面试题看channel在select场景下的注意事项
- Go Quiz: 从Go面试题看defer语义的底层原理和注意事项
- Go Quiz: 从Go面试题看defer的注意事项第2篇
- Go Quiz: 从Go面试题看defer的注意事项第3篇
- Go Quiz: 从Go面试题看分号规则和switch的注意事项
公众号:coding进阶。关注公众号可以获取最新Go面试题和技术栈。
个人网站:Jincheng's Blog。
知乎:无忌。
References
- https://github.com/golang/go/issues/50792
- https://github.com/golang/go/issues/50348
- Sub-repositories - pkg.go.dev
推荐阅读
- golang|官方博文(Go 1.18发布啦)
- python|一文看懂 Go 泛型核心设计
- 开源日报|Log4j 漏洞最早由阿里云团队发现;HashiCorp 挂牌上市,市值 152 亿美元;Go 1.18 Beta1 发布 | 开源日报
- golang|一文读懂Go泛型设计和使用场景
- 大数据项目总结|基于Java+springmvc+vue 健康管理系统
- 艾瑞(技术驱动、生态助力,移动应用行业展望“黄金十年”)
- Stats 102 Homework 4分析
- CS 2113软件工程
- C语言|C语言开发专题(56个案例)-程序设计 - 课程设计