Golang – 隐藏空结构体的 JSON 响应

huangapple go评论73阅读模式
英文:

Golang - Hiding empty struct from JSON Response

问题

我正在尝试使ErrorSuccess结构在其中一个为空时消失。

package main

import (
	"encoding/json"
	"net/http"
)

type appReturn struct {
	Suc *Success `json:"success,omitempty"`
	Err *Error   `json:"error,omitempty"`
}

type Error struct {
	Code    int    `json:"code,omitempty"`
	Message string `json:"message,omitempty"`
}

type Success struct {
	Code    int    `json:"code,omitempty"`
	Message string `json:"message,omitempty"`
}

func init() {
	http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
	j := appReturn{&Success{}, &Error{}}

	js, _ := json.Marshal(&j)
	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

输出:

{
    "success": { },
    "error": { }
}

我该如何隐藏JSON输出中的ErrorSuccess结构?
我以为将指针作为参数发送会起作用。

英文:

I'm trying to make the Error and Success struct disappear if either one of them is empty

package main

import (
	"encoding/json"
	"net/http"
)

type appReturn struct {
	Suc *Success `json:"success,omitempty"`
	Err *Error   `json:"error,omitempty"`
}

type Error struct {
	Code    int    `json:"code,omitempty"`
	Message string `json:"message,omitempty"`
}

type Success struct {
	Code    int    `json:"code,omitempty"`
	Message string `json:"message,omitempty"`
}

func init() {
	http.HandleFunc("/", handler)
}

func handler(w http.ResponseWriter, r *http.Request) {
	j := appReturn{&Success{}, &Error{}}

	js, _ := json.Marshal(&j)
	w.Header().Set("Content-Type", "application/json")
	w.Write(js)
}

Output:

{
    success: { },
    error: { }
}

How can I hide the Error or Success struct from the JSON output?
I thought that sending the pointer as an argument would do the trick.

答案1

得分: 2

这是因为appReturn.SucappReturn.Err不是空的;它们包含指向已初始化结构体的指针,其中恰好包含了空指针。唯一的空指针是nil指针。

将appReturn初始化为j := appReturn{}

英文:

This is because appReturn.Suc and appReturn.Err are not empty; they contain pointers to initialized structs, which just happen to have nil pointers inside. The only empty pointer is a nil pointer.

Initialize appReturn as j := appReturn{}

答案2

得分: 2

你可以将其中一个参数设置为nil,使其消失:

http://play.golang.org/p/9Say6mVzCg

j := appReturn{&Success{}, nil}
js, _ := json.Marshal(&j)
fmt.Println(string(js))
j = appReturn{nil, &Error{}}
js, _ = json.Marshal(&j)
fmt.Println(string(js))
j = appReturn{nil, nil}
js, _ = json.Marshal(&j)
fmt.Println(string(js))

如果由于某种原因你不能这样做,你也可以编写一个自定义的JSON编组器来检查空结构体:

http://play.golang.org/p/W0UhB4qtXH

func (j appReturn) MarshalJSON() ([]byte, error) {
    suc, _ := json.Marshal(j.Suc)
    err, _ := json.Marshal(j.Err)
    if (string(err) == "{}") {
       return []byte("{\"success\":" + string(suc) + "}"), nil
    } else {
        return []byte("{\"error\":" + string(err) + "}"), nil
    }
}
英文:

You can pass in nil for either argument to make it disappear:

http://play.golang.org/p/9Say6mVzCg

j := appReturn{&Success{}, nil}
js, _ := json.Marshal(&j)
fmt.Println(string(js))
j = appReturn{nil, &Error{}}
js, _ = json.Marshal(&j)
fmt.Println(string(js))
j = appReturn{nil, nil}
js, _ = json.Marshal(&j)
fmt.Println(string(js))

If for whatever reason you can't do that, you could also write a custom JSON marshaler to check for the empty struct:

http://play.golang.org/p/W0UhB4qtXH

func (j appReturn) MarshalJSON() ([]byte, error) {
    suc, _ := json.Marshal(j.Suc)
    err, _ := json.Marshal(j.Err)
    if (string(err) == "{}") {
       return []byte("{\"success\":" + string(suc) + "}"), nil
    } else {
	    return []byte("{\"error\":" + string(err) + "}"), nil
    }
} 

huangapple
  • 本文由 发表于 2014年9月3日 01:04:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/25628682.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定