遍历结构的集合(切片)的通用方法

I have following code in Go:

type Foo struct { Id int }
type Bar struct { Id int }

func getIdsFoo(foos []Foo) {
  ids = make([]int, len(foos))
  // iterate and get all ids to ids array
}

func getIdsBar(bars []Bar) {
  ids = make([]int, len(bars))
  // iterate and get all ids to ids array
}

Is there a clever way to create a function getIds([]Idable) that can take any struct that have method GetId() implemented?

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.

type Identifiable interface {
    GetId() int
}

func GatherIds(ys []Identifiable) []int {
    xs := make([]int, 0, len(ys))
    for _, i := range ys {
        xs = append(xs, i.GetId())
    }
    return xs
}