vendredi 21 août 2015

go (reflect): How to Instantiate an arbitrary type and set a known embedded field

Consider the following type declaration:

type (
    Embedded struct{}
    Actual1 struct{ *Embedded }
    Actual2 struct{ *Embedded }
    Actual3 struct{ *Embedded }
)

Now consider the following function, where i may be of type Actual1, Actual2, or Actual3 (or any other type that embeds Embedded in like manner). I can't do a type assertion or a type switch because I can't know how many types contain Embedded, all I know about i is that it does indeed embed the Embedded type. This function will instantiate a new instance of the same type as i and set embed on that newly instantiated copy instance.

func New(i interface{}, field *Embedded) interface{} {
    // Step 1. instantiate new instance of `i`, of same underlying type as `i`
    // Step 2. set `i.Embedded` to `field`
    // Step 3. return the new instance.
}

Here's what usage would look like:

func main() {
    actual := &Actual1{}
    embed := &Embedded{}
    copied := New(actual, embed)
    if copied.(Actual1).Embedded != embed {
        log.Fatal("It didn't work!")
    }
}

A correct implementation of the New(...) function cannot use type assertions or a type switch and would also not result in the call to log.Fatal shown above.

I think what I'm asking for is a combination of these two questions:





Aucun commentaire:

Enregistrer un commentaire