2016-06-03 9 views
5

Jak automatycznie dodać pole type do każdego serializowanego JSON-a w Go?Jak automatycznie dodać pole typu do JSON w Go?

Na przykład, w tym kodzie:

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

Zamiast generować coś takiego:

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

Chciałbym wygenerować to:

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

Odpowiedz

4

można zastąpić Funkcja MarshalJSON dla twojej struktury, aby wprowadzić typ do pomocniczej struktury, która następnie zostaje zwrócona.

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

Czy jest jakiś sposób, aby to zrobić, zastępując 'MarshalJSON' raz (może dla' interfejsu {} 'lub czegoś), zamiast dla każdej struktury? –

Powiązane problemy