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

我在玩 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 格式的错误)......以一种巧妙抽象的方式。


慕妹3242003
浏览 218回答 2
2回答

DIEA

要解决您的 json 问题,您可以使用一个结构并用 json:"omitempty" 标记每个字段:package mainimport (    "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

拉风的咖菲猫

我在我的应用程序上使用 map 而不是 struct ,尤其是当我想向客户端返回一个 json 答案时。它给了我更多的灵活性。请看看这个:package mainimport (    "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.1uploadStatus : success你可以在这里查看:http : //play.golang.org/p/h4b4-nkZ4M
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go