背景
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.
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 as
func(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.
该提议也同 Go 语言发明者 Rob Pike, Robert Griesemer 和 Ian Lance Taylor 做过探讨,失去了他们的批准。
其中 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 的注意事项
开源地址
文章和示例代码开源在 GitHub: Go 语言高级、中级和高级教程。
公众号:coding 进阶。关注公众号能够获取最新 Go 面试题和技术栈。
集体网站:Jincheng’s Blog。
知乎:无忌。
References
- https://github.com/golang/go/…
- https://github.com/golang/go/…
- https://pkg.go.dev/golang.org/x