如何在go中排列不同结构类型的列表

如何在go中排列不同结构类型的列表,go,Go,我和Go一起工作才几天。我定义了一小部分不同的结构类型,每个结构类型都包含一个日期 不知何故,我需要按日期顺序处理这些结构,但这种顺序必须跨越多个不同的结构类型。在动态类型语言(如Python)中,只需创建按日期键入的所有对象的散列(如果列表不是唯一的,则创建列表散列)就很容易了。在C语言中,我可以使用指针的并集或void*。但我被困在如何在Go中实现这一点上 我想我可以保留每种类型的排序列表,并在运行时进行手动合并排序。看起来很糟糕 我所读到的关于处理这种情况的内容似乎指向使用接口,但我不知道

我和Go一起工作才几天。我定义了一小部分不同的结构类型,每个结构类型都包含一个日期

不知何故,我需要按日期顺序处理这些结构,但这种顺序必须跨越多个不同的结构类型。在动态类型语言(如Python)中,只需创建按日期键入的所有对象的散列(如果列表不是唯一的,则创建列表散列)就很容易了。在C语言中,我可以使用指针的并集或void*。但我被困在如何在Go中实现这一点上

我想我可以保留每种类型的排序列表,并在运行时进行手动合并排序。看起来很糟糕

我所读到的关于处理这种情况的内容似乎指向使用接口,但我不知道在这种情况下如何使用它们

为了便于讨论,我们假设我有这样的东西:

type A struct {
    Date string
    Info string
}

type B struct {
    Date string
    Info int
}
(虽然实际上有更多的结构,而且它们更复杂,有多个字段),只需按日期顺序打印每个结构(未排序)数组的内容

是否有办法创建指向非统一对象类型的列表(日期、指针)对


根据以下第一条建议:

package main
import "fmt"

type A struct {
    Date string
    Info string
}
func (x *A) GetDate() string {
    return x.Date
}
type B struct {
    Date string
    Info int
}
func (x *B) GetDate() string {
    return x.Date
}

type Dater interface {
    GetDate() string
}

type Daters []Dater
func (s Daters) Len() int      { return len(s) }
func (s Daters) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
type ByDate struct{ Daters }
func (s ByDate) Less(i, j int) bool {
    return s.Daters[i].GetDate() < s.Daters[j].GetDate()
}   

func main() {
    // lista and listb are just examples. They really come from elsewhere
    lista := []A{{"2012/08/01", "one"}, {"2012/08/03", "three"}}
    listb := []B{{"2012/08/02", 2}, {"2012/08/04", 4}}

    x := make([]Dater, len(lista) + len(listb))
    index := 0
    for i := range(lista) {
        x[index] = &lista[i]
        index++
    }
    for i := range(listb) {
        x[index] = &listb[i]
        index++
    }
    sort.Sort(ByDate{x})
    for _,v := range(x) {
        fmt.Printf("%#v\n", v)
    }
}
主程序包
输入“fmt”
类型A结构{
日期字符串
信息字符串
}
func(x*A)GetDate()字符串{
报税表x.日期
}
B型结构{
日期字符串
信息整型
}
func(x*B)GetDate()字符串{
报税表x.日期
}
类型日期器接口{
GetDate()字符串
}
类型日期器[]日期器
func(s日期)Len()int{return Len(s)}
func(s日期者)Swap(i,j int){s[i],s[j]=s[j],s[i]}
类型ByDate结构{Daters}
func(s ByDate)减去(i,j int)bool{
返回s.Daters[i].GetDate()
真管用!所以界面的基本用法很好,我开始理解了 界面稍微好一点-谢谢

注意:x的创建非常难看。我看不到更干净/更惯用的方法了?

用方法(比如返回日期的getDate())定义接口(比如Date)。然后让所有结构(A、B、C)实现接口。然后可以定义use[]Dated来保存类型值

您可能希望检查包的“时间”和“排序”以简化实现

您可能可以使用

您可以定义一个只包含日期的结构,然后将其嵌入其他结构中。这样,您只需实现GetDate()一次。您还可以随时扩展日期结构,而无需修改其他结构

package main

type Dater interface {
    GetDate() string
}

type Date struct {
    Date string
}

func (d *Date) GetDate() string {
    return d.Date
}

type A struct {
    Date
    Info string
}

type B struct {
    Date
    Info []byte
}

type C struct {
    Date
    Info int32
}

现在,您可以在A、B和C上调用GetDate()。

非常小的命名nit:一个名为“Dater”的接口和一个名为“Date()”的方法将更惯用Go命名。@uriel在这种情况下,您将如何处理名为Date的字段这一事实?惯用的解决方案是什么?谢谢-效果很好。我让它工作(见更新的问题),即使它不是最漂亮的;-)事实证明我不能这么做——因为隐藏在我给你的简化背后的原因。我正在从XML解析结构,XML模块将填充原始结构-这些不同的日期字段需要不同的标记才能正确填充。总的来说,你说的话似乎很管用!