(この質問のフォローアップとして:ネストされた構造体初期化リテラル)。
簡単に記述できるリテラルで構造体を初期化できるようになったので、コードの後半で親構造体のメンバーにアクセスする必要がありますが、具体的な派生型はわかりません。こんな感じです:
type A struct {
MemberA string
}
type B struct {
A
MemberB string
}
そして、私はそれを次のように使用します:
b := B {
A: A { MemberA: "test1" },
MemberB: "test2",
}
fmt.Printf("%+v\n", 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\n", a)
} else {
fmt.Printf("Aristotle (and John Galt) be damned! A is NOT A\n")
}
// no go
私が見るオプションは次のとおりです。
リフレクションを使用して "A" というメンバーを探し、それが適切な型であると仮定してそれを使用できます。これは実行可能ですが、効率が悪く、確かに「不格好」です。
HasA { Aval() A }
呼び出し元に ( A のインスタンスを返す類似の) インターフェイスを実装するように要求することができます。もう 1 つのポイントは、呼び出し元に A 値を渡させることができるということです (つまり、上記の例では、
var i interface{} = b
becomevar i A = b.A
)。しかし、何が起こっているのかというと、私は実際に B のメンバーを動的に繰り返し処理し、それらを処理するため、そのためにはより多くの「派生」型が必要です。(これは、なぜ私がこれに遭遇したのかという背景にすぎず、質問の技術的な回答には関係ないため、質問から省略しました。)
Java の場合のように、「A にキャスト」できれば素晴らしいと思います。それを行うためのよりエレガントな方法はありますか。