我可以使用MarshalJSON向golang中的json编码添加任意字段吗?
假设我已经编写了以下代码段。操场上为有兴趣的人提供完整的代码我可以使用MarshalJSON向golang中的json编码添加任意字段吗?,json,go,Json,Go,假设我已经编写了以下代码段。操场上为有兴趣的人提供完整的代码 type Book struct { Title string Author string } func main() { ms := Book{"Catch-22", "Joseph Heller"} out, err := json.MarshalIndent(ms, "", " ") if err != nil { log.Fatalln(err) } fmt.P
type Book struct {
Title string
Author string
}
func main() {
ms := Book{"Catch-22", "Joseph Heller"}
out, err := json.MarshalIndent(ms, "", " ")
if err != nil {
log.Fatalln(err)
}
fmt.Println(string(out))
}
这段代码输出以下内容,与我预期的完全一致:
{
"Title": "Catch-22",
"Author": "Joseph Heller"
}
假设我想在JSON输出中添加一个字段,而不将其包含在书
结构中。也许是一种类型:
{
"Title": "Catch-22",
"Author": "Joseph Heller",
"Genre": "Satire"
}
我可以使用MarshalJSON()
在Marshal()
上向JSON负载添加任意字段吗?比如:
func (b *Book) MarshalJSON() ([]byte, error) {
// some code
}
其他人让我认为这应该是可能的,但我正在努力找出实现 这个问题的一个可能答案是struct literal(),尽管我希望它更一般一些,不需要重新映射所有的struct字段:
func (b *Book) MarshalJSON() ([]byte, error) {
return json.Marshal(struct{
Title string
Author string
Genre string
} {
Title: b.Title,
Author: b.Author,
Genre: "Satire",
})
}
这里有一个比我上一个更好的答案
type FakeBook Book
func (b Book) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
FakeBook
Genre string
}{
FakeBook: FakeBook(b),
Genre: "Satire",
})
}
由于匿名结构字段是“合并”的(还有一些额外的注意事项),我们可以使用它来避免重新映射单个字段。请注意,使用了FakeBook
类型以避免出现无限递归
操场:整理
地图是解决问题的另一种方法
tmap:=make(映射[字符串]接口{})
tmap[“struct”]=struct{
StructValue字符串`json:“struct_value”`
}{
“价值02”,
}
tmap[“字符串”]=“值01”
out,err:=json.marshallindent(tmap,“,”)
如果出错!=零{
log.Fatalln(错误)
}
fmt.Println(字符串(输出))
这将输出:
{
“字符串”:“值01”,
“结构”:{
“结构值”:“值02”
}
}
如果您有许多任意键名,这可能是一个很好的解决方案
操场:这是一种处理方法:
类型对象结构{
一串
B int
额外映射[字符串]接口{}`json:“-”`
}
func(o对象)MarshalJSON()([]字节,错误){
类型Object_uuObject
b、 err:=json.Marshal(对象_uo))
如果错误!=零{
返回零,错误
}
如果o.Extra==nil | | len(o.Extra)==0{
返回b,无
}
m、 err:=json.Marshal(o.Extra)
如果错误!=零{
返回零,错误
}
如果len(b)==2{
返回m,零
}否则{
b[len(b)-1]=','
返回append(b,m[1:]…),nil
}
}
您可以将任何附加字段添加到Extra
映射中,这些字段将显示在输出中而不嵌套