添加一个字段到 JSON ( 结构 + 接口 ) golang

这是响应接口:


type Response interface{}

它满足于这样的结构:


type CheckResponse struct {

    Status    string `json:"status"`

}

我正在获得一个输出,它将在其他地方消费。out []Response


我想在发送之前向此 JSON 添加一个字符串。我尝试过使用匿名结构(但徒劳无功):Version


for _, d := range out {

        outd := struct {

            Resp       Response `json:",inline"`

            Version    string   `json:",inline"`

        }{

            Resp:       d,

            Version: "1.1",

        }

        data, _ := json.Marshal(outd)

        log.Infof("response : %s", data)

    }

我得到的输出是:


response : {"Resp":{"status":"UP"},"Version":"1.1"}

我想要的是

{"status":"UP","Version":"1.1"}

即一个平面 JSON。


米脂
浏览 118回答 3
3回答

叮当猫咪

断言您的检查响应类型,然后像这样定义动态结构doutd := struct {            Resp       string `json:"status,inline"`            Version    string   `json:",inline"`        }这是完整的代码。package mainimport (    "encoding/json"    "fmt")type Response interface {}type CheckResponse struct {    Status    string `json:"status"`}func main() {    out := []Response{        CheckResponse{Status: "UP"},    }    for _, d := range out {        res, ok := d.(CheckResponse)        if !ok {            continue        }        outd := struct {            Resp       string `json:"status,inline"`            Version    string   `json:",inline"`        }{            Resp:       res.Status,            Version: "1.1",        }        data, _ := json.Marshal(outd)        fmt.Printf("response : %s", data)    }}你可以在这里运行

天涯尽头无女友

inline标记不受 支持,嵌入接口也不会产生您想要的结果。您必须为值声明一个类型,并让该类型实现接口,然后您可以自定义其字段的封送方式,例如,您可以分别封送两个字段 Resp 和 Version,然后将结果“合并”到单个 json 对象中。encoding/jsonoutjson.Marshalertype VersionedResponse struct {    Resp    Response    Version string}func (r VersionedResponse) MarshalJSON() ([]byte, error) {    out1, err := json.Marshal(r.Resp)    if err != nil {        return nil, err    }    out2, err := json.Marshal(struct{ Version string }{r.Version})    if err != nil {        return nil, err    }    // NOTE: if Resp can hold something that after marshaling    // produces something other than a json object, you'll have    // to be more careful about how you gonna merge the two outputs.    //    // For example if Resp is nil then out1 will be []byte(`null`)    // If Resp is a slice then out1 will be []byte(`[ ... ]`)    out1[len(out1)-1] = ',' // replace '}' with ','    out2 = out2[1:]         // remove leading '{'    return append(out1, out2...), nil}https://play.golang.org/p/66jIYXGUtWJ

哆啦的时光机

一种确定可行的方法是简单地使用 ,通过反射迭代中的字段,或者使用像 ,使用响应字段更新映射,将版本字段附加到映射,然后封送。下面是一个示例map[string]interface{}Responsestructspackage mainimport (    "encoding/json"    "fmt"    "github.com/fatih/structs")type Response interface{}type CheckResponse struct {    Status string `json:"status"`}func main() {    resp := CheckResponse{Status: "success"}    m := structs.Map(resp)    m["Version"] = "0.1"    out, _ := json.Marshal(m)           fmt.Println(string(out))}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go