go - 从父方法访问所有字段

标签 go struct dry embedding

我正在开发一个将数据存储在 mongodb 中的应用程序。有几个集合,当然它们都有一些共同的字段(如 Id、创建日期等)和方法(例如 Insert)。在我的设想中,我需要创建具有所需字段和方法的基本模型结构,然后将此结构嵌入到我的模型中。不幸的是,这不起作用,因为为基本模型定义的方法看不到子字段。

我不知道如何进一步解释。这是 Playground 上的代码: https://play.golang.org/p/_x-B78g4TV

它使用json而不是mgo,但是idea还是一样。

我希望输出为:

Saving to 'my_model_collection'

{"_id":42, "foo": "Some value for foo", "bar": "Here we set some value for bar"}

不是:

Saving to 'my_model_collection'

{"_id":42}

为我的每个模型编写插入方法似乎有悖于 DRY,那么在 Go 中实现此目的的正确/惯用方法是什么?

最佳答案

这是不可能的,详情见我的回答:Can embedded struct method have knowledge of parent/child?

你可以做两件事:

1。放弃方法并使其成为辅助/实用函数

想法是让 Insert()BaseModel 分离,并使它成为一个简单的函数,然后将要保存的文档传递给它。

我个人更喜欢这个选项,因为它需要更少的麻烦和维护。它可能看起来像这样:

func Insert(doc interface{}) {
    j, _ := json.Marshal(doc)
    fmt.Println(string(j))
}

您在标签中也有一个“拼写错误”:

type MyModel struct {
    *BaseModel
    Foo string `json:"foo"`
    Bar string `json:"bar"`
}

使用它:

Insert(m)

输出(在 Go Playground 上尝试):

{"_id":42,"foo":"Some value for foo","bar":"Here we set some value for bar"}

2。将包装器(指向)传递给 BaseModel

在这种方法中,您必须传递一个指向嵌入器结构的指针,这样 BaseModel.Insert() 方法就会有一个指向它的指针,并且可以使用它来保存/编码。这基本上是手动维护对嵌入我们并正在保存/编码的结构的“引用”。

它可能是这样的:

type BaseModel struct {
    Id             int `json:"_id"`
    collectionName string

    wrapper interface{}
}

然后在 Insert() 方法中保存 wrapper:

func (m *BaseModel) Insert() {
    fmt.Printf("Saving to '%v'\n", m.collectionName)
    j, _ := json.Marshal(m.wrapper)
    fmt.Println(string(j))
}

创建稍微复杂一些:

func NewMyModel() *MyModel {
    mm := &MyModel{
        Foo: "Some value for foo",
    }
    mm.BaseModel = NewBaseModel("my_model_collection", mm)
    return mm
}

但输出如你所愿:

Saving to 'my_model_collection'
{"_id":42,"foo":"Some value for foo","bar":"Here we set some value for bar"}

Go Playground 上试试.

关于go - 从父方法访问所有字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40215326/

相关文章:

go - 具有非固定类型参数的函数

C 中节俭的编码示例,使用文件

dry - 在 LilyPond 中,你如何改变音乐表达?

javascript - 是否有一种 DRY(er) 方法将项目添加到数组中?

angularjs - go gorilla/sessions angularjs and path, session values not saved (find the bug/place the blame)

csv - 从 go-kit golang 中的 API 请求解析 CSV 文件

c - 使用嵌入式C中的指定初始化程序初始化结构。“期望表达式”

ruby - 嵌套两个具有可选参数的自定义 Liquid 标签

function - Go - 函数返回日期时间

c - 将结构作为值参数传递给线程