4

我有一个我想有效地进行 JSON 编码的结构:

type MyStruct struct {
    *Meta
    Contents []interface{}
}

type Meta struct {
    Id int
}

该结构包含已知形式的元数据和未知形式的内容,内容列表在运行时填充,因此我无法控制它们。为了提高 Go 的编组速度,我想在 Meta 结构上实现 Marshaller 接口。Marshaller 界面如下所示:

type Marshaler interface {
        MarshalJSON() ([]byte, error)
}

请记住,元结构并不像这里显示的那么简单。我已经尝试在 Meta 结构上实现 Marshaler 接口,但似乎当我然后 JSON 编组 MyStruct 时,结果只是 Meta 编组接口返回的结果。

所以我的问题是:我如何对一个结构进行 JSON 编组,该结构包含具有自己的 JSON 编组器的嵌入式结构和另一个没有 JSON 编组器的结构?

4

1 回答 1

4

由于MarshalJSON匿名字段的方法*Meta将被提升为MyStruct,因此encoding/json包将在编组 MyStruct 时使用该方法。

您可以做的是,您可以像这样在 MyStruct 上实现接口,而不是让Meta实现接口:Marshaller

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,"Contents":["MyForm",12]}

操场

于 2013-08-30T08:39:01.100 回答