lundi 7 mai 2018

Reflect on list of interfaces

I have read several examples/questions about reflection in Go, but I'm still unable to understand what I'm supposed to do with my list of interfaces.

Below is a stripped down version of the real use case.

I have several types complying with a given interface:

type Foo interface {
    Value() int
}

type bar struct {
    value int
}

func (b bar) Value() int {
    return b.value
}

type baz struct{}

func (b baz) Value() int {
    return 42
}

I have a list of such guys

type Foos []Foo
var foos = Foos{
    bar{},
    baz{},
}

and I would like to traverse this list by changing the value of the members that have a value field.

    for k := range foos {
        change(&foos[k])
    }

But I'm unable to find the right path

func change(g *Foo) {
    t := reflect.TypeOf(g).Elem()
    fmt.Printf("t: Kind %v, %#v\n", t.Kind(), t)
    v := reflect.ValueOf(g).Elem()
    fmt.Printf("v: Kind %v, %#v, %v\n", v.Kind(), v, v.CanAddr())
    if f, ok := t.FieldByName("value"); ok {
        fmt.Printf("f: %#v, OK: %v\n", f, ok)
        vf := v.FieldByName("value")
        fmt.Printf("vf: %#v: %v\n", vf, vf.CanAddr())
        vf.SetInt(51)
    }
}

As you can see, I'm not sure how to glue together the TypeOf and ValueOf bits...

The full example is on Go Playground.





Aucun commentaire:

Enregistrer un commentaire