Jon*_*Jon 3 polymorphism struct go
我正在创建一个API,我有两个不同的结构用于JSON响应; 一个用于单个记录,一个用于记录收集:
type Model struct {
Id uint
}
type Collection struct {
Records []Model
}
Run Code Online (Sandbox Code Playgroud)
A Model只是数据库数据的结构表示(例如,用户),a Collection是模型的集合.
问题是将嵌入Model类型的单独结构,如下所示:
type User struct {
*Model
Name string
}
Run Code Online (Sandbox Code Playgroud)
并且由于a User不满足Model类型,我不能将它附加到这样的Collection结构:
user := User{&Model{1}, "Jon"}
uc := &Collection{[]User{user}}
Run Code Online (Sandbox Code Playgroud)
如何使Records结构接受实现的结构类型Model?
您有两种选择:
实现单独收集像UserCollection,BarCollection,FooCollection是一个选项,如果你没有太多的Foo和酒吧.
另一种方法是使用通用空接口类型interface{},它将保存任何类型的值(因为每种类型的每个实例都满足空接口):
type Collection struct {
Records []interface{}
}
Run Code Online (Sandbox Code Playgroud)
这有许多缺点,例如每次访问Records字段时都必须执行类型断言,您可以错误地将所有内容放在那里,并且必须使用反射来执行大多数操作.
使用接口的更好方法是实现模型接口,让每个作为模型的类型实现接口:
type Model interface {
ImplementsModel()
}
type BaseModel struct {
Id uint
}
func (b *BaseModel) ImplementsModel() {}
type User struct {
*BaseModel
Name string
}
type Collection struct {
Records []Model
}
Run Code Online (Sandbox Code Playgroud)
当然,ImplementsModel一旦有了有意义的方法,就可以删除虚拟方法.这个虚拟方法就是将接口与空接口区分开来,这样就不能将整数值或字符串代替实际模型放入集合中.