在Go中的嵌入式结构上实现json marshaller [英] Implementing json marshaller over embedded stuct in Go

查看:99
本文介绍了在Go中的嵌入式结构上实现json marshaller的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个想要高效地进行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?

推荐答案

由于匿名字段*MetaMarshalJSON方法将被升级为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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆