英文:
Generic function for getting different attribute in go
问题
我有这样的代码:
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, ???)) // 获取 foo_id
fmt.Println(ids(foos, ???)) // 获取 other_id
fmt.Println(ids(foos, ???)) // 获取 one_more_id
fmt.Println(ids(bars, ???)) // 获取 bar_id
}
我想让ids
函数具有通用性,以便能够传递任何结构体和需要检索的属性(通过闭包?)。有没有办法可以做到这一点?或者也许我应该采用不同的方法?
编辑:
我的问题太模糊了,我必须澄清一下:
ids
函数应该能够从结构体中获取多个字段,具体取决于需要,就像我上面更新的代码一样。
英文:
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.
答案1
得分: 5
使用接口是否符合您的要求....
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)) // 获取 foo_id [1 3]
fmt.Println(ids(bars)) // 获取 bar_id [2 5]
fmt.Println(ids(bazs)) // 获取 bar_id, foo_id, bar_id [3 4 6]
}
英文:
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]
}
答案2
得分: 2
这对你的情况可以起作用:
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
}
Playground链接。在这个示例中,我使用了类型开关(Type Switch)。如果你不知道要期望哪些类型,你需要使用reflect包(reflect package)。但是,根据你的示例,你将无法访问未导出的字段。
英文:
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.
1: http://play.golang.org/p/MeKPX2-GDC "Playground"
2: http://golang.org/ref/spec#Type_switches "Type Switch"
3: http://golang.org/pkg/reflect/ "reflect package"
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论