(As a followup this question: nested struct initialization literals).
Now that I can initialize a struct with literals that are easy to write, I later in my code need access members of the parent struct, but without knowing the concrete derived type. It's like this:
type A struct {
MemberA string
}
type B struct {
A
MemberB string
}
And then I use it like this:
b := B {
A: A { MemberA: "test1" },
MemberB: "test2",
}
fmt.Printf("%+v
", b)
var i interface{} = b
// later in the code, I only know that I have something that has a nested A,
// I don't know about B (because A is in a library and B is in the
// calling code that uses the library).
// so I want to say "give me the A out of i", so I try a type assertion
if a, ok := i.(A); ok {
fmt.Printf("Yup, A is A: %+v
", a)
} else {
fmt.Printf("Aristotle (and John Galt) be damned! A is NOT A
")
}
// no go
The options I see are:
I could use reflection to look for a member called "A" and, assuming it's the right type, use it. This would be workable but less efficient and certainly more "clunky".
I could require the caller to implement an interface (like
HasA { Aval() A }
or similar which returns an instance of A. So far this is the best idea I could think of.The other point is that I could just have the caller pass a A value (i.e. in the example above,
var i interface{} = b
becomesvar i A = b.A
). But what's happening is I actually dynamically iterate over the members of B and do stuff with them, so I need that more "derived" type in order to that. (I've omitted that from the question because it's more just background as to why I'm running into this and is not pertinent to the technical answer of the question.)
It would be great if I could just "cast it to A", as you would in Java. Is there a more elegant way to do that.