获取Go语言中不同属性的通用函数

huangapple go评论120阅读模式
英文:

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"

huangapple
  • 本文由 发表于 2014年7月10日 16:38:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/24671930.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定