This particular case
In this particular case, you should not use 2 different types, since they are identical, just use the generic type Animal :
type Animal struct { Name string Age int } func (a Animal) String() string { return fmt.Sprintf("%s(%d)", a.Name, a.Age) } type SortAnim []*Animal func (c SortAnim) Len() int { return len(c) } func (c SortAnim) Swap(i, j int) { c[i], c[j] = c[j], c[i] } func (c SortAnim) Less(i, j int) bool { return c[i].Age < c[j].Age } func main() { dogs := []*Animal{&Animal{"Max", 4}, &Animal{"Buddy", 3}} cats := []*Animal{&Animal{"Bella", 4}, &Animal{"Kitty", 3}} fmt.Println(dogs) sort.Sort(SortAnim(dogs)) fmt.Println(dogs) fmt.Println(cats) sort.Sort(SortAnim(cats)) fmt.Println(cats) }
Conclusion ( Go to the playground ):
[Max(4) Buddy(3)] [Buddy(3) Max(4)] [Bella(4) Kitty(3)] [Kitty(3) Bella(4)]
General case
In general, you can only use the general sorting implementation if you want to discard specific types and use interface types.
Create the type of interface you want your fragment to hold on to:
type Animal interface { Name() string Age() int }
You may have a general implementation:
type animal struct { name string age int } func (a *animal) Name() string { return a.name } func (a *animal) Age() int { return a.age } func (a animal) String() string { return fmt.Sprintf("%s(%d)", a.name, a.age) }
Your specific types of animals:
type Dog struct { animal
You implement sort.Interface on SortAnim :
type SortAnim []Animal func (c SortAnim) Len() int { return len(c) } func (c SortAnim) Swap(i, j int) { c[i], c[j] = c[j], c[i] } func (c SortAnim) Less(i, j int) bool { return c[i].Age() < c[j].Age() }
Using:
dogs := SortAnim{&Dog{animal{"Max", 4}}, &Dog{animal{"Buddy", 3}}} cats := SortAnim{&Cat{animal{"Bella", 4}}, &Cat{animal{"Kitty", 3}}} fmt.Println(dogs) sort.Sort(SortAnim(dogs)) fmt.Println(dogs) fmt.Println(cats) sort.Sort(SortAnim(cats)) fmt.Println(cats)
Conclusion ( Go to the site ):
[Max(4) Buddy(3)] [Buddy(3) Max(4)] [Bella(4) Kitty(3)] [Kitty(3) Bella(4)]