How to order a list of different types of structures in go

I have been working with Go for several days. I have a small number of different types of structure, each of which contains a date.

Somehow I need to process these structures in order of dates, but this ordering should cover several different types of structures. In a dynamically typed language like Python, it's easy to just create a hash of all objects given by date (or a hash of lists if they are not unique). In C, I can use pointer joins or void *. But I'm stuck on how to do this in Go.

I suppose I can save a sorted list of each type and do a manual merge while I go. It seems klunky?

What I read about handling this situation seems to indicate the use of interfaces, but I don’t see how to use them in this situation.

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

type A struct { Date string Info string } type B struct { Date string Info int } 

(Although in practice there are more structures, and they are more complicated with several fields), and you just need to print in the date the order of the contents of the (unsorted) array of each of them.

Is there a way to create pairs (date, pointer) for an uneven object type?


First sentence 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\n", v) } } 

It works! So, the main use of the interface is great, and I'm starting to understand the interfaces a little better - thanks!

Note. Making x is pretty ugly. I do not see a cleaner / more idiomatic path?

+4
source share
2 answers

Define an interface (e.g. Dated) using a method (e.g. getDate () that returns Date). Then all structures (A, B, C) implement the Dated interface. You can then define the use of [] Dated to store type values.

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

+3
source

You might be able to use embedding .

You must define a structure that contains only the date, and then insert it into others. This way you only need to implement GetDate () once. You can also extend the Date structure at any time without changing other structures.

 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 } 

Now you can call GetDate () on A, B and C.

0
source

Source: https://habr.com/ru/post/1434518/


All Articles