2

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?

2 Answers 2

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 } 
Sign up to request clarification or add additional context in comments.

3 Comments

[]Foo cannot be cast to []Identifiable, even if Foo implements the Identifiable interface.
Typo: append(xs, i) => append(xs, i.GetId())
@deft_code I noticed that it can't be cast becouse it is O(n) operation, but is it true? Do you have some reading about it?
2

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.

1 Comment

Why downvote? Its a perfect anwser. Only think I need is to write generators and it will work :) Is there any posibility of using embeding here to avoid generating Len() and GetId() over and over again?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.