简体   繁体   English

是否有可能在杜松子酒绑定的 json 中消失 scope?

[英]Is it possible that disappearing a scope in gin-gonic binded json?

I'm writing an api server with gin-gonic.我正在用 gin-gonic 编写 api 服务器。

And I got in trouble that associated with marshaling json.我遇到了与编组 json 相关的麻烦。

For example, I have a Structure likes below.例如,我有一个如下所示的结构。

type Foo struct {
    Value     float32 `json:"value"`
    Injection interface{}
}

And I wrote down some fields in run time and send response.我在运行时写下了一些字段并发送响应。

r.GET("/ping", func(c *gin.Context) {

    var foo = &Foo{
        Value: 19.8,
        Injection: map[string]interface{}{
            "unit": "C",
            "constraints": map[string]interface{}{
                "min": 18,
                "max": 30,
            },
        },
    }

    c.JSON(200, foo)
})

As a result, I can see this json response.结果,我可以看到这个 json 响应。

{
    "value": 19.8,
    "Injection": {
        "constraints": {
            "max": 30,
            "min": 18
        },
        "unit": "C"
    }
}

But if I want to have likes below, what can I do?但是如果我想在下面有喜欢,我该怎么办?

{
    "value": 19.8,
    "constraints": {
        "max": 30,
        "min": 18
    },
    "unit": "C"
}

I tried to assign all field in run time, It's work properly in first time, but after add many many fields I met hell gate.我尝试在运行时分配所有字段,它在第一次正常工作,但在添加了许多字段后我遇到了地狱门。

So I can say It's similar problem <Fragment> tag in React.所以我可以说这是 React 中的类似问题<Fragment>标签。

ps.附言。 sorry I can't sure the title is correspond with my mean.抱歉,我不能确定标题是否符合我的意思。

You can use the map directly instead of Foo .您可以直接使用 map 而不是Foo

r.GET("/ping", func(c *gin.Context) {
    var data = map[string]interface{}{
        "value": 19.8,
        "unit":  "C",
        "constraints": map[string]interface{}{
            "min": 18,
            "max": 30,
        },
    }

    c.JSON(200, data)
})

If you need something more generic you could have Foo implement the json.Marshaler interface and have the implementation marshal the two values separately and then just "merge" the results manually.如果您需要更通用的东西,您可以让Foo实现json.Marshaler接口,并让实现分别编组这两个值,然后手动“合并”结果。

type Foo struct {
    Value     float32     `json:"value"`
    Injection interface{} `json:"-"`
}

func (f *Foo) MarshalJSON() ([]byte, error) {
    type tmp Foo
    out1, err := json.Marshal((*tmp)(f))
    if err != nil {
        return nil, err
    }
    out2, err := json.Marshal(f.Injection)
    if err != nil {
        return nil, err
    }

    out1[len(out1)-1] = ','           // replace the '}' at the end with ','
    out2 = out2[1:]                   // drop the leading '{'
    return append(out1, out2...), nil // merge
}

Note the above assumes that Injection holds a value that will be marshaled into a json object , if the value is a scalar, or a slice type, you'll need to handle those cases differently.请注意,上述假设Injection包含一个将被编组为 json object的值,如果该值是标量或切片类型,则需要以不同方式处理这些情况。

https://play.golang.com/p/kYIu6HnqVIp https://play.golang.com/p/kYIu6HnqVIp

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM