为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
米脂 2022-09-19 14:45:45
这是响应接口:type Response interface{}它满足于这样的结构:type CheckResponse struct {    Status    string `json:"status"`}我正在获得一个输出,它将在其他地方消费。out []Response我想在发送之前向此 JSON 添加一个字符串。我尝试过使用匿名结构(但徒劳无功):Versionfor _, 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。
查看完整描述

3 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

断言您的检查响应类型,然后像这样定义动态结构d


outd := struct {

            Resp       string `json:"status,inline"`

            Version    string   `json:",inline"`

        }

这是完整的代码。


package main


import (

    "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)

    }

}

你可以在这里运行


查看完整回答
反对 回复 2022-09-19
?
天涯尽头无女友

TA贡献1831条经验 获得超9个赞

inline标记不受 支持,嵌入接口也不会产生您想要的结果。您必须为值声明一个类型,并让该类型实现接口,然后您可以自定义其字段的封送方式,例如,您可以分别封送两个字段 Resp 和 Version,然后将结果“合并”到单个 json 对象中。encoding/jsonoutjson.Marshaler


type 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


查看完整回答
反对 回复 2022-09-19
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

一种确定可行的方法是简单地使用 ,通过反射迭代中的字段,或者使用像 ,使用响应字段更新映射,将版本字段附加到映射,然后封送。下面是一个示例map[string]interface{}Responsestructs


package main


import (

    "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))

}


查看完整回答
反对 回复 2022-09-19
  • 3 回答
  • 0 关注
  • 117 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信