定义一种具有比较能力的类型是一种常见需求,比如对一组相同类型的值进行排序,就需要进行两两比较,那么在Go语言中有没有办法定义一种具有比较能力的Interface,实现该接口的类型都具备比较能力呢,最常见最容易的办法是定义一个与 any 比较的接口方法:
type Comparable interface {
func LessThen(a any) bool
}
func Sort[T Comparable] (s []T) {
// s[i].LessThen(s[j])
}
具体实现的时候进行类型断言:
type User struct {
Age int
}
func(u *User) LessThen(a any) bool {
u2, ok := a.(*User)
if !ok {
return false
}
return u.Age < u2.Age
}
多少缺点意思,没办法约束比较目标的类型与自己相同,于是我们想到可以利用 Go1.18 引入的范型来约束比较目标类型,于是 Comparable 定义改进为:
type Comparable[T any] interface {
func LessThen(t T) bool
}
实现改变为:
// 实现接口 Comparable[*User]
func(u *User) LessThen(u2 *User) bool {
return u.Age < u2.Age
}
随之 Sort 方法也要修改:
func Sort[T Comparable[*User]] (s []T) {
// s[i].LessThen(s[j])
}
但这样的 Sort 方法限制了 T 只能与 *User 比较,要想 T 具有与自身类型比较的能力,Sort 定义需要再次修改:
func Sort[T Comparable[T]] (s []T) {
// s[i].LessThen(s[j])
}
这样的 Sort 方法定义就比较通用了,基本实现了我们最初的目标,虽然看起来有点晦涩难懂,但好在接口实现比较简单, 比如:
type Int int
func (i Int) LessThen(o Int) bool {
return i < o
}
Sort([]Int{3, 5, 7})
type Time time.Time
func (t Time) LessThen(t2 Time) bool {
return time.Time(t).Before(time.Time(o))
}
Sort([]Time{Time(time.Now()), Time(time.Now().Add(-time.Minute))})
期待后面版本的 Go 语言的 Interface 和范型加入对 self 的支持,这样的话我们的接口定义就会变得简单直接,比如:
// 伪代码,无法编译
// 限制它的实现必须是与实现者自身类型比较,而不是其他类型
type Comparable interface {
func LessThen(t self) bool
}
Golang 2 目前有一个提案就是讨论关于 self的: https://github.com/golang/go/issues/28254,有兴趣也可以关注参与
1180

被折叠的 条评论
为什么被折叠?



