I have such to code:
package main
import "fmt"
type Foo struct {
foo_id int
other_id int
one_more_id int
}
type Bar struct {
bar_id int
}
func ids(???) []int { ??? }
func main() {
foos := {Foo{1},Foo{3}}
bars := {Bar{1},Bar{3}}
fmt.Println(ids(foos, ???)) // get foo_id
fmt.Println(ids(foos, ???)) // get other_id
fmt.Println(ids(foos, ???)) // get one_more_id
fmt.Println(ids(bars, ???)) // get bar_id
}
I would like to make ids
generic, to be able to pass there any structure and somehow (closure?) and attribute which I need to retrive. Is there a mean to do it? Or maybe I should use different approach?
EDIT: My question was too ambigous, I have to clear it out: ids
function should be able to get more then one field from struct, depending on needs, as I updated above code.
Does using an interface suit your requirements....
https://play.golang.org/p/aQiw-D4ME5
package main
import "fmt"
type ThingWithID interface {
ID() int
}
type Foo struct {
foo_id int
}
func (f Foo) ID() int {
return f.foo_id
}
type Bar struct {
bar_id int
}
func (b Bar) ID() int {
return b.bar_id
}
func ids(things []ThingWithID) []int {
ia := []int{}
for _,t := range things {
ia = append(ia, t.ID())
}
return ia
}
func main() {
foos := []ThingWithID{Foo{1}, Foo{3}}
bars := []ThingWithID{Bar{2}, Bar{5}}
bazs := []ThingWithID{Bar{3}, Foo{4}, Bar{6}}
fmt.Println(ids(foos)) // get foo_id [1 3]
fmt.Println(ids(bars)) // get bar_id [2 5]
fmt.Println(ids(bazs)) // get bar_id, foo_id, bar_id [3 4 6]
}
This would work for your case:
func ids(gens []interface{}) []int {
ids := []int{}
for _, i := range gens {
switch foobar := i.(type) {
case Foo:
ids = append(ids, foobar.foo_id)
case Bar:
ids = append(ids, foobar.bar_id)
default:
continue
}
}
return ids
}
The Playground Link. I am using a Type Switch in this example. If you don't know which types to expect, you would need to use the reflect package. But you wouldn't have access to the unexported fields as defined in your example.