struct - 嵌入式类型和结构的多态性

标签 struct go polymorphism

我正在创建一个 API,我有两种不同的 JSON 响应结构;一种用于单个记录,一种用于收集记录:

type Model struct {
  Id uint
}

type Collection struct {
  Records []Model
}

Model 只是数据库数据(例如,用户)的结构表示,Collection 是模型的集合。

问题是会有单独的结构嵌入 Model 类型,如下所示:

type User struct {
    *Model
    Name string
}

因为 User 不满足 Model 类型,我不能像这样将它附加到 Collection 结构中:

user := User{&Model{1}, "Jon"}
uc := &Collection{[]User{user}}

如何让 Records 结构接受实现 Model 的结构类型?

最佳答案

你有两个选择:

  • 创建另一种集合类型
  • 改用接口(interface)

如果您没有太多的 foos 和 bars,可以选择实现单独的集合,例如 UserCollectionBarCollectionFooCollection

另一种方法是使用通用的空接口(interface)类型 interface{},它将保存任何类型的值(因为每种类型的每个实例都满足空接口(interface)):

type Collection struct {
    Records []interface{}
}

这有很多缺点,例如每次访问 Records 字段时都必须进行类型断言,您可能会错误地将所有内容放在那里,并且您必须使用反射进行大多数操作。

使用接口(interface)的更好方法是实现一个模型接口(interface),并让作为模型的每个类型都实现该接口(interface):

type Model interface {
    ImplementsModel()
}

type BaseModel struct {
    Id uint
}

func (b *BaseModel) ImplementsModel() {}

type User struct {
    *BaseModel
    Name string
}

type Collection struct {
    Records []Model
}

当然,一旦有了有意义的方法,您就可以删除 ImplementsModel 虚拟方法。这个虚拟方法只是用来区分接口(interface)和空接口(interface),这样你就不能将整数值或字符串代替实际模型放入集合中。

关于struct - 嵌入式类型和结构的多态性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32981576/

相关文章:

xml - 如何从不在重复项中使用结束标记的嵌套 xml 中获取数据?

go - 初始化 map 的更好方法是什么?

Mysql查询以获取一对多关系并扫描到结构

go - 在多个go例程中返回先前的Wait之前,WaitGroup被重用

Java 多态行为

c - 使用 typedef 结构时无效使用未定义类型

c - 如何使指针 == null 测试通过?

c++ - 如何在 C++ 中调用泛型结构

c# - 基于类型的条件逻辑

DELPHI:泛型和多态性