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

动态返回不同类型的 JSON 结构?

动态返回不同类型的 JSON 结构?

Go
慕妹3242003 2022-01-04 10:49:08
我在玩 Go 并且无法将我的一些“继承”设计从其他语言适应到它的结构。我已经用 OCaml 和其他一些具有类似结构的语言进行了编码,但我很困惑。如果没有类型继承,使用共享结构从不同地方返回 JSON 会变得有点奇怪。我必须根据需要递归地遍历输入数据以构建单个 JSON 对象以进行响应。举个例子:{    "appVersion": "1.0.0",    "messageStatus": "received"}... 和:{    "appVersion": "1.0.0",    "uploadStatus": "received"}到目前为止,我可以找到在 Go 中完成这项工作的唯一方法是将包含“appVersion”的基本结构分别复制并粘贴到两个输出生成函数中,但我不想这样做,因为我不想必须两次维护同一组代码。这是我试图解决这个问题的地方:type JSONResponse struct {    appVersion string}type MessageJSONResponse struct {    JSONResponse    messageStatus string}type UploadJSONResponse struct {    JSONResponse    uploadStatus string}... 然后:type Message struct {    formattingVersion *int}func NewMessageObject(r *http.Request) (bool, *MessageJSONResponse) {    message := new(Message)    if (true) {        // #TODO: INSERT LOGIC HERE!        *message.formattingVersion = 2;    }    if (message.formattingVersion != nil) {        response := new(MessageJSONResponse)        response.messageStatus = "OK"        return false, errorResponse    }    return true, nil}... 和:func init() {    http.Handle("/endpoints/message", JSONResponseHandler(messageHandler))}func JSONResponseHandler(h func (w http.ResponseWriter, r *http.Request) interface {}) http.Handler {// #TODO - convert `JSONResponse` into actual JSON or output JSON Error!}func messageHandler(w http.ResponseWriter, r *http.Request) JSONResponse { // #BROKEN TYPES?    hasError, messageResponse := NewMessageObject(r)    if (hasError || messageResponse==nil) { return nil } // #TODO    ////    // #TODO ... more message things.    return messageResponse;};这种方法(对不起任何代码错误,真的很长的一天,我要睡觉了)不起作用,因为为了传递不同的返回值......类型不能改变,等等。该JSONResponseHandler包装方法确实可以工作在我结束,但只有与interface {}类型给定式的变化......所以我离开它,因为它会弄乱代码。但是,如果我interface {}在带有可选星号返回属性(例如“NewMessageObject”)的后续块上使用,则 JSON 构造函数似乎会忽略这些值,因为它们被包装在一个空接口中,而不仅仅是作为其原始类型公开。但是,他们必须有一个零选项......怎么了?一般的设计?我基本上是在尝试通过基于输入数据的后续调用构建一个 JSON 对象响应(或返回一个 JSON 格式的错误)......以一种巧妙抽象的方式。
查看完整描述

2 回答

?
DIEA

TA贡献1820条经验 获得超3个赞

要解决您的 json 问题,您可以使用一个结构并用 json:"omitempty" 标记每个字段:


package main


import (

    "encoding/json"

    "fmt"

)


type foostruct struct {

    Myfoo   string `json:"myfoo,omitempty"`

    Yourfoo string `json:"yourfoo,omitempty"`

    Ourfoo string `json:"ourfoo,omitempty"`

}


func main() {

    j := []byte("{\"myfoo\":\"mine\", \"yourfoo\":\"yours\"}")

    fstruct := &foostruct{}

    err := json.Unmarshal(j, fstruct)

    if err != nil {

        panic(err)

    }


    b, err := json.Marshal(fstruct)

    if err != nil {

        panic(err)

    }


    fmt.Println(string(b))

}

您将看到输出不包含字段“ourfoo”:


{"myfoo":"mine","yourfoo":"yours"}

在这里试试:http : //play.golang.org/p/zKwFaxbLJu


查看完整回答
反对 回复 2022-01-04
?
拉风的咖菲猫

TA贡献1995条经验 获得超2个赞

我在我的应用程序上使用 map 而不是 struct ,尤其是当我想向客户端返回一个 json 答案时。它给了我更多的灵活性。请看看这个:


package main


import (

    "encoding/json"

    "fmt"

)


func main() {

    m := make(map[string]interface{})

    m["appVersion"] = "0.0.1"

    m["uploadStatus"] = "success"


    strJson, _ := json.Marshal(m)

    str := string(strJson)

    fmt.Println("---ENCODING--")

    fmt.Println(str)


    //put it back

    fmt.Println("---DECODING--")

    n := make(map[string]interface{})

    json.Unmarshal([]byte(str), &n)

    for key, val := range n {

        fmt.Println(key, ":", val)

    }

}

输出是:


---ENCODING--

{"appVersion":"0.0.1","uploadStatus":"success"}

---DECODING--

appVersion : 0.0.1

uploadStatus : success

你可以在这里查看:http : //play.golang.org/p/h4b4-nkZ4M


查看完整回答
反对 回复 2022-01-04
  • 2 回答
  • 0 关注
  • 217 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号