下面的示例包含 2 个接口(interface) Foo
和 Bar
,它们都实现了相同的接口(interface) Timestamper
。它还包含实现 sort.Interface 的类型 ByTimestamp
.
如函数 main
所示,我想使用类型 ByTimestamp
对 Foo
的 slice 和 slice 进行排序条形图
。但是,代码将无法编译,因为它无法将 foos(类型 []Foo)转换为 ByTimestamp 类型
,并且无法将 bars(类型 []Bar)转换为 ByTimestamp 类型
。
是否可以使用实现 sort.Interface
的单一类型对实现相同接口(interface)的 2 个不同接口(interface) slice 进行排序?
package main
import (
"sort"
)
type Timestamper interface {
Timestamp() int64
}
type ByTimestamp []Timestamper
func (b ByTimestamp) Len() int {
return len(b)
}
func (b ByTimestamp) Swap(i, j int) {
b[i], b[j] = b[j], b[i]
}
func (b ByTimestamp) Less(i, j int) bool {
return b[i].Timestamp() < b[j].Timestamp()
}
type Foo interface {
Timestamper
DoFoo() error
}
type Bar interface {
Timestamper
DoBar() error
}
func getFoos() (foos []Foo) {
// TODO get foos
return
}
func getBars() (bars []Bar) {
// TODO get bars
return
}
func main() {
foos := getFoos()
bars := getBars()
sort.Sort(ByTimestamp(foos))
sort.Sort(ByTimestamp(bars))
}
最佳答案
是的,可以使用一个sort.Interface
对不同类型进行排序。
但不是你试图做的方式。当前的 Go 规范不允许将一种 slice 类型转换为另一种 slice 类型。您必须转换每个项目。
这是一个使用反射完成它的辅助函数:
// ByTimestamp converts a slice of Timestamper into a slice
// that can be sorted by timestamp.
func ByTimestamp(slice interface{}) sort.Interface {
value := reflect.ValueOf(slice)
length := value.Len()
b := make(byTimestamp, 0, length)
for i := 0; i < length; i++ {
b = append(b, value.Index(i).Interface().(Timestamper))
}
return b
}
查看完整示例 here .
而且,如果您只有几种类型,那么进行特定于类型的转换可能更有意义。
关于sorting - go type conversion - 使用共享接口(interface)对 2 片不同的接口(interface)进行排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49341895/