golang 如何定义一种能够与自身类型值进行比较的Interface
定义一种具有比较能力的类型是一种常见需求,比如对一组相同类型的值进行排序,就需要进行两两比较,那么在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 intfunc (i Int) LessThen(o Int) bool {return i < o
}Sort([]Int{3, 5, 7})type Time time.Timefunc (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,有兴趣也可以关注参与