duanhuau567787 2012-09-17 02:29
浏览 23
已采纳

如何在Go中订购不同结构类型的列表

I've only been working with Go for a couple of days. I have a small variety of different structure types defined, each of which contains a date.

Somehow I need to process those structures in date order, but that ordering has to span across the multiple different structure types. In a dynamically typed language like Python, it's easy to just create a hash of all the objects keyed by date (or hash of lists if they're not unique). In C, I can use unions of pointers or void*. But I'm stuck as to how do this in Go.

I guess I could keep a sorted list of each type and do a manual mergesort as I go. Seems klunky?

What I've read about handling this sort of situation seems to point to using interfaces, but I don't really see how to use them in this situation.

For the sake of argument, let's say I have something like:

type A struct {
    Date string
    Info string
}

type B struct {
    Date string
    Info int
}

(Though in practice there are more structures, and they are more complex with multiple fields), and just need to print in date order the contents of an (unsorted) array of each of them.

Is there some way to create a list (date, pointer) pairs to a non-uniform object type?


Per first suggestion below:

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
", v)
    }
}

That works! So the basic use of interface is fine, and I'm starting to understand interfaces a little better - thank you!

Note: The creation of x is pretty ugly. I can't see a cleaner / more idiomatic way?

  • 写回答

2条回答 默认 最新

  • 普通网友 2012-09-17 03:04
    关注

    Define a interface (say Dated) with a method (say getDate() that returns Date). Then have all structs (A, B, C) implementing Dated interface. Then you can define use []Dated to hold your type values.

    You might want to check package 'time' and 'sort' to simplify the implementation.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 chaquopy python 安卓
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 有没有帮写代码做实验仿真的
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥30 vmware exsi重置后登不上
  • ¥15 易盾点选的cb参数怎么解啊
  • ¥15 MATLAB运行显示错误,如何解决?
  • ¥15 c++头文件不能识别CDialog
  • ¥15 Excel发现不可读取的内容
  • ¥15 关于#stm32#的问题:CANOpen的PDO同步传输问题