(В следующем вопросе: nested struct initialization literals).Вложенная структура - получить «базовую» структуру
Теперь, когда я могу инициализировать структуру литералами, которые легко писать, я позже в своем коде нуждаюсь в доступе к родительской структуре, но не знаю конкретного производного типа. Это как это:
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 }
или аналогичный, который возвращает экземпляр А. До сих пор это самая лучшая идея, я мог думать.Другое дело, что я мог бы просто получим, что вызывающий абонент передает значение А (т.е. в приведенном выше примере,
var i interface{} = b
становитсяvar i A = b.A
). Но то, что происходит, я фактически динамически перебираю членов B и делаю с ними все, поэтому мне нужен этот более «производный» тип в порядке к этому. (Я опустил это из вопроса, потому что это скорее просто справочная информация о том, почему я столкнулся с этим и не уместен для технического ответа на вопрос.)
Было бы здорово, если бы я мог просто «бросить его на А», как в Java. Есть ли более элегантный способ сделать это.
Я вижу. Поскольку A реализует AEmbedder, то B, путем вложенности делает также ... Это кажется довольно выполнимым и простым. Это также означает, что когда вы выполняете 'var i AEmbedder = b', тип времени выполнения значения в' i' по-прежнему B - так что итерация по его полям и т. Д. Дает мне результаты из более производного времени. Довольно рад. Я думаю, что это именно то, что я хочу. (Если я вообще не смогу избежать этого, как вы упомянули). –