迭代结构集合(切片)的通用方法

时间:2014-02-25 12:42:08

标签: go

我在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
}

是否有一种聪明的方法来创建一个函数getIds([]Idable),它可以采用任何实现方法GetId()的结构?

2 个答案:

答案 0 :(得分:3)

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
}

答案 1 :(得分:1)

sort使用可能对您有帮助的设计模式。

创建一个适用于类切片接口的函数。然后根据您的具体类型创建新类型。

希望代码比我的描述更清晰。 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)))
}

还有更多的样板,而不是令人愉快的,(Go仿制药......总有一天)。最大的好处是不需要将新方法添加到FooBar或您可能需要使用的任何未来类型。