在Go中的嵌入式结构上实现json marshaller [英] Implementing json marshaller over embedded stuct in Go
问题描述
我有一个想要高效地进行JSON编码的结构:
I have a struct that I would like to efficiently JSON encode:
type MyStruct struct {
*Meta
Contents []interface{}
}
type Meta struct {
Id int
}
该结构包含已知形式的元数据和未知形式的内容,内容列表在运行时填充,因此我实际上没有控制权.为了提高Go的编组速度,我想在Meta结构上实现Marshaller接口. Marshaller界面如下所示:
The struct contains meta data of a known form and Contents of an unknown form, The contents list is populated during runtime, so I don't really have control over them. To improve Go's marshalling speed, I would like to implement the Marshaller interface over the Meta struct. The Marshaller interface looks like this:
type Marshaler interface {
MarshalJSON() ([]byte, error)
}
请记住,Meta结构并不像这里所示的那么简单.我已经尝试过在Meta结构上实现Marshaler接口,但是似乎当我随后将JSON编组MyStruct时,结果只是Meta编组接口返回的结果.
Please keep in mind that the Meta struct is not as simple as shown here. I've tried implementing the Marshaler interface over the Meta struct, but it seems that when I then JSON marshal MyStruct, the result is only the result returned by the Meta marshalling interface.
所以我的问题是:如何以JSON封送一个结构,该结构包含带有嵌入式struct和自己的JSON编组器以及另一个不带JSON的结构?
So my question is: How can I JSON marshal a struct, that contains en embedded struct with its own JSON marshaller and another struct without one?
推荐答案
由于匿名字段*Meta
的MarshalJSON
方法将被升级为MyStruct
,因此当MyStruct将使用encoding/json
包时,该encoding/json
包将使用该方法.被封送.
Since the MarshalJSON
method of the anonymous field *Meta
will be promoted to MyStruct
, the encoding/json
package will use that method when MyStruct will be marshalled.
您可以做的是,您可以像这样在MyStruct上实现该接口,而不是让Meta
实现Marshaller
接口:
What you can do is, instead of letting Meta
implement the Marshaller
interface, you can implement the interface on MyStruct like this:
package main
import (
"fmt"
"encoding/json"
"strconv"
)
type MyStruct struct {
*Meta
Contents []interface{}
}
type Meta struct {
Id int
}
func (m *MyStruct) MarshalJSON() ([]byte, error) {
// Here you do the marshalling of Meta
meta := `"Id":` + strconv.Itoa(m.Meta.Id)
// Manually calling Marshal for Contents
cont, err := json.Marshal(m.Contents)
if err != nil {
return nil, err
}
// Stitching it all together
return []byte(`{` + meta + `,"Contents":` + string(cont) + `}`), nil
}
func main() {
str := &MyStruct{&Meta{Id:42}, []interface{}{"MyForm", 12}}
o, err := json.Marshal(str)
if err != nil {
panic(err)
}
fmt.Println(string(o))
}
{"Id":42,内容":["MyForm",12]}
{"Id":42,"Contents":["MyForm",12]}
这篇关于在Go中的嵌入式结构上实现json marshaller的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!