如何在Go中自动将类型字段添加到JSON?

时间:2016-06-03 10:45:52

标签: json go

如何自动为Go中的每个序列化JSON添加type字段?

例如,在此代码中:

type Literal struct {
  Value interface{} `json:'value'`
  Raw   string      `json:'raw'`
}

type BinaryExpression struct {
  Operator string  `json:"operator"`
  Right    Literal `json:"right"`
  Left     Literal `json:"left"`
}

os.Stdout.Write(json.Marshal(&BinaryExpression{ ... }))

而不是生成类似的东西:

{
   "operator": "*",
   "left": {
      "value": 6,
      "raw": "6"
   },
   "right": {
      "value": 7,
      "raw": "7"
   }
}

我想生成这个:

{
   "type": "BinaryExpression",
   "operator": "*",
   "left": {
      "type": "Literal",
      "value": 6,
      "raw": "6"
   },
   "right": {
      "type": "Literal",
      "value": 7,
      "raw": "7"
   }
}

1 个答案:

答案 0 :(得分:4)

您可以覆盖结构的MarshalJSON函数,将类型注入到辅助结构中,然后返回。

package main

import (
    "encoding/json"
    "os"
)

type Literal struct {
    Value interface{} `json:'value'`
    Raw   string      `json:'raw'`
}

func (l *Literal) MarshalJSON() ([]byte, error) {
    type Alias Literal
    return json.Marshal(&struct {
        Type string `json:"type"`
        *Alias
    }{
        Type:  "Literal",
        Alias: (*Alias)(l),
    })
}

type BinaryExpression struct {
    Operator string  `json:"operator"`
    Right    Literal `json:"right"`
    Left     Literal `json:"left"`
}

func (b *BinaryExpression) MarshalJSON() ([]byte, error) {
    type Alias BinaryExpression
    return json.Marshal(&struct {
        Type string `json:"type"`
        *Alias
    }{
        Type:  "BinaryExpression",
        Alias: (*Alias)(b),
    })
}

func main() {
    _ = json.NewEncoder(os.Stdout).Encode(
        &BinaryExpression{
            Operator: "*",
            Right: Literal{
                Value: 6,
                Raw:   "6",
            },
            Left: Literal{
                Value: 7,
                Raw:   "7",
            },
        })
}