如何创建嵌入不同其他对象的可重用对象?

时间:2018-02-02 05:09:32

标签: go

我有很多不同的模型:

type objectModel struct {
        Title string `json:"title"`
        Body string `json:"body"`
}

// Many more models...

这些模型用于创建返回给客户端的响应对象。所有响应必须包含布尔值OK;其他领域取决于背景。

type objectResponse struct {
        OK bool `json:"ok"`
        Object *objectModel `json:"object"`
}

type objectListResponse struct {
        OK bool `json:"ok"`
        Objects []*objectModel `json:"objects"`
}

// Many more response types that are similar to these two examples.

问题

我想要的是一个可重用的response对象,它嵌入了所有这些不同的自定义响应对象objectResponseobjectListResponse等等。在这种情况下,我不需要在每个响应对象上定义OK bool。我会这样使用它:response.write(responseWriter),但这超出了这个问题的范围。

type response struct {
    OK bool `json:"ok"`
    CustomResponse
}

应该可以使用界面,但我不知道所有响应应该实现的常用方法。

2 个答案:

答案 0 :(得分:1)

  

我想要的是一个可重用的响应对象,它嵌入了所有这些不同的自定义响应对象objectResponse,objectListResponse等。在这种情况下,我不需要在每个响应对象上定义OK bool。

反过来说:如何在自定义响应对象中嵌入可重用的Response对象?这将允许您不在每个响应对象(您声明的目标)上定义OK bool,您只需在每个响应结构中嵌入Response结构。如果还有其他重复字段,那么您也可以使用相同的嵌入式结构,如果它们只属于某些自定义响应,则使用另一个结构。

这是一个简化的工作示例:

package main

import(
    "fmt"
    "encoding/json"
)

type Response struct {
    OK          bool        `json:"ok"`
}

type lookResponse struct {
    Response
    Color       string      `json:"color"`
    Shape       string      `json:"shape"`
}

func main() {
    b := []byte(`{"ok":true,"color":"blue","shape":"circle"}`)
    var r lookResponse
    err := json.Unmarshal(b, &r)
    if err != nil {
        fmt.Printf("Error: %s\n", err)
    }
    fmt.Printf("ok: %v, color: %v, shape: %v\n", r.OK, r.Color, r.Shape)
}

运行时打印:

ok: true, color: blue, shape: circle

您可以在Go Language Specification中阅读有关嵌入字段的更多信息,例如:

  

使用类型但没有显式字段名称声明的字段称为   embedded field ...结构中嵌入字段的字段或方法f   如果x.f是表示它的合法选择器,则x被称为提升   领域或方法f。推广的字段就像一个普通的字段   struct除了它们不能用作复合中的字段名称   结构的文字。

如果这不能解决您的问题,请澄清您的目标/问题。

答案 1 :(得分:0)

我会在那里使用interface{}。例如:

type response struct {
    OK bool `json:"ok"`
    Object interface{} `json:"object"`
}

现在,当我想使用时,我可以在其中放置任何其他类型:

res := response{
    OK: true,
    Object: varOfCustomObjectModel,
}

这是我用于我的一个项目的响应对象: https://github.com/leninhasda/gitpull-me/blob/master/api/response.go

用例:

res := &response{
    StatusCode: http.StatusOK,
    Data: map[string]interface{}{
        "product_title": "Awesome Product",
        "price": 188.99,
        "quantity": 1,
        "meta": map[string]interface{}{
            "height": 10,
            "width": 15,
        },
    },
    // or as simple as just 
    // Data: "hello world!"
}
res.json(w) // w is http.ResponseWriter