sort uses a design patter that might help you.
Create a function that works on an slice-like interface. Then create new types based off of a slice of your concrete types.
Hopefully, the code is more clear than my description. http://play.golang.org/p/TL6yxZZUWT
type IdGetter interface { GetId(i int) int Len() int } func GetIds(ig IdGetter) []int { ids := make([]int, ig.Len()) for i := range ids { ids[i] = ig.GetId(i) } return ids } type Foo struct{ Id int } type Bar struct{ Id int } type FooIdGetter []Foo func (f FooIdGetter) GetId(i int) int { return f[i].Id } func (f FooIdGetter) Len() int { return len(f) } type BarIdGetter []Bar func (b BarIdGetter) GetId(i int) int { return b[i].Id } func (b BarIdGetter) Len() int { return len(b) } func main() { var f = []Foo{{5}, {6}, {7}} var b = []Bar{{10}, {11}, {12}} fmt.Println("foo ids:", GetIds(FooIdGetter(f))) fmt.Println("bar ids:", GetIds(BarIdGetter(b))) }
There is still a bit more boilerplate than is pleasant, (Go generics... someday). It's greatest advantage is that new methods do not need to be added to Foo, Bar, or any future type you may need to work with.