inheritance - golang 继承来实现像集合/模型这样的主干

标签 inheritance go data-structures collections embedding

我正在研究 golang 作为我的网络后端的新 goto 语言。我目前使用的语言是 PHP,我在其中实现了类似于 Backbone Collection/Model 结构的数据结构。

excursus 集合/模型

这意味着我有一个包含多个模型CollectionModels 有一个 attributes 字典用于存储实际的“公共(public)数据”。 Collections 有多个对 Models 数组进行操作的便捷方法(sort、getByIndex、getByMatchingParameter 等)。 模型也有一些方便的方法。

在日常生活中,90% 的“事物”都会以相同的方式表示。例如,我可以像存储 User 一样存储 Address。有一个包含我的 AddressesAddressesCollection 我可以简单地要求我的 AddressesCollection 给我所有的 AddressModels 其中 city =柏林。在我的基类中实现这个匹配,我可以在我的 UserCollection 上做逻辑上相同的事情,给我所有被 deactivated=true 停用的用户。

但有时(10%)我需要一种特殊的方法。 getGeoData 用于 Addresses 例如。现在,在我的 oop 世界中,我可以简单地创建一个新类来扩展我的 BaseModel 添加我的方法,并在使用我的基类的任何地方使用我的扩展类。

我的“我就是不明白”

这在 Go 中是如何工作的。我读了很多关于嵌入/合成的介绍。但是根本不要让我头疼。

这就是我的立场,请记住这是我学习“继承”概念的 Playground ,而不是用于生产就绪的集合/模型实现。

GoPlayground

我得到的是我还没有“理解”如何编写接受不完全继承类型的“通用”方法。我有一种感觉,我必须在某处使用一个接口(interface)来获得这种“继承”/“扩展类”的感觉。但我目前对它的使用是……好吧……

但也许我在 go 中以这种方式实现我想要的结构的概念完全错误?也许有一种更优雅的方式。非常感谢任何提示!

最佳答案

您已经很接近正确了,但是您混淆了多种不同的东西。

完整示例:https://play.golang.org/p/wpj82QRVUP

  1. 类型嵌入

所以你有两个模型UserAddress,它们共享公共(public)字段,也许还有方法。这是为两者创建通用结构的一个很好的理由:Model,如上面的链接所示。 这三个结构都是不同的类型

  1. 收藏

您可以拥有接口(interface)的集合或已定义类型的集合。那么什么时候使用哪个呢?

如果你有一个地址集合,定义如下类型: 键入 AddrCollection []*Address。然后在 AddrCollection 类型上实现您想要的任何方法。

如果您有一个模型集合,类似地定义 type ModelCollection []*Model,但是随后将 Address 传递给 ModelCollection 将需要“提取”嵌入类型。

如果你有一些东西的集合,那么定义一个接口(interface)集合(示例中的 DescriberCollection),但是你不会在上面定义 GetByAddress() , 它只会存在于 AddrCollection

  1. 接口(interface)

它们没有字段,它们只定义要实现的方法签名。在 Go 中,接口(interface)通常被接受并且永远不会返回,这让你有一个好处,那就是拥有干净和面向目标的设计。接口(interface)是一种允许其他用户(或其他包)使用您的包/库的方式,他们不需要实现您的类型,而是某些方法。他们可以重用您定义的类型,或者他们可以插入他们自己的接口(interface)实现。那么什么是接口(interface),就是一种说法:这里有一套方法签名,只要你实现了就可以使用我的包

关于inheritance - golang 继承来实现像集合/模型这样的主干,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44470806/

相关文章:

C++ 虚函数表现怪异

database - 使用 ORM 模型而不是正确的数据库建模

macos - `go get` 因某些 go 包的权限被拒绝而失败

c - 我的循环链表代码有什么问题?

c++ - C++ 中的基本继承问题

c++ - 当继承只为某些最终类型引入先决条件时如何记录/断言

c++ - 复制 C++ 抽象类

go - 按引用或按值扫描函数

c - 链表节点内存分配

c++ - 为 codechef 中的每个代码获取 SIGEMT 错误