首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >go类型转换-使用共享接口对不同接口的2个切片进行排序

go类型转换-使用共享接口对不同接口的2个切片进行排序
EN

Stack Overflow用户
提问于 2018-03-18 05:04:06
回答 1查看 76关注 0票数 0

下面的示例包含两个接口FooBar,它们都实现了相同的接口Timestamper。它还包含实现sort.Interface的类型ByTimestamp

如函数main中所示,我希望使用类型ByTimestamp来对Foos和Bars的片段进行排序。但是,代码将不会编译,因为它是cannot convert foos (type []Foo) to type ByTimestampcannot convert bars (type []Bar) to type ByTimestamp

是否可以对两个不同接口的片段进行排序,这两个片段都实现了相同的接口,并且具有实现sort.Interface的单个类型

代码语言:javascript
复制
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))
}

The Go playground

EN

回答 1

Stack Overflow用户

发布于 2018-03-19 04:10:31

是的,可以使用一个sort.Interface对不同的类型进行排序。但不是你想要的方式。当前的Go规范不允许将一种切片类型转换为另一种切片类型。你必须转换每一项。

下面是一个辅助函数,它使用反射来完成此任务:

代码语言:javascript
复制
// 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

而且,如果您只有几种类型,那么进行特定于类型的转换可能更有意义。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49341895

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档