2016-06-03 31 views
5

Come aggiungere automaticamente un campo type a ogni JSON serializzato in Go?Come aggiungere automaticamente un campo tipo a JSON in Go?

Ad esempio, in questo codice:

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{ ... })) 

Invece di generare qualcosa come:

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

vorrei generare questo:

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

risposta

4

È possibile ignorare il Funzione MarshalJSON per la tua struttura per iniettare il tipo in una struttura ausiliaria che viene poi restituita.

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", 
      }, 
     }) 
} 
+0

C'è un modo per farlo sovrascrivendo 'MarshalJSON' una volta (forse per' interface {} 'o qualcosa), invece che per ogni struct? –