这个问题最好用一个例子来描述
http://play.golang.org/p/bQuRr0kV-b
我正在尝试创建一个可组合的结构。在这个例子中,我希望有一个Person类型,其中包含来自Female或Male的嵌入值。如果我只是处理结构,我会像这样嵌入它们
type Person Struct{
Female
Male
}
我不能这样做,因为在实际项目中,有很多嵌入式结构,我宁愿保持结构清洁和可组合。但是也存在命名冲突 - 在这个例子中,男性和女性都包含“眼睛”字段。将冲突值移动到Person结构不是一个可行的解决方案(因为许多其他嵌入式结构不包含该特定值)。
我希望通过简单的界面传递这些值。下面的示例:运行此代码时,我得到&{Name: Age:0 Type:male GenderType:0x10434120}
其中GenderType是指向Male结构的指针(在本例中)。我的目标是返回一个看起来像&{Name: Age:0 Type:male Eyes: ChestSize:0}
package main
import "fmt"
type Person struct {
Name string
Age int
Type string
GenderType
}
type GenderType interface {
TypeName() string
}
type Male struct {
Eyes string
ChestSize int
}
type Female struct {
Eyes string
BustSize int
}
func (m *Male) TypeName() string {
return "male"
}
func (f *Female) TypeName() string {
return "female"
}
func main() {
d := NewHuman(new(Male))
fmt.Printf("%+v", d)
}
func NewHuman(gt GenderType) *Person {
return &Person{
Type: gt.TypeName(),
GenderType: gt,
}
}
答案 0 :(得分:2)
我不认为可以在平面结构中执行此操作,因为它需要在运行时更改结构类型的内存结构,这是不允许的。虽然您可以使用GenderType访问嵌入字段,但它仍然是允许的,因为您说这将是对满足接口的嵌入式结构的引用,而不是更改结构本身的结构。
我认为使用此方法编组成平面json的更好方法是保留嵌入式结构,但然后使Person结构成为Marshaler
您可以添加自己的自定义MarshalJSON()(byte [],error)方法,并使用它来生成平面json输出。
如果您需要专门的解组,那么您也可以使用与Person关联的(UnmarshalJSON([] byte)错误)方法。
请参阅https://golang.org/pkg/encoding/json/#Marshaler以获取进一步的参考资料
这是一个展示我的意思的游乐场:https://play.golang.org/p/qOl9WSaI3O