2015-07-17 43 views
9
type Struct struct { 
    Value string `json:"value"` 
    Value1 string `json:"value_one"` 
    Nest Nested `json:"nest"` 
} 

type Nested struct { 
    Something string `json:"something"` 
} 

Desidero aggiungere elementi che non sono nelle definizioni di struct senza creare un altro tipo di struttura. Per esempioGolang modifica json senza struct

Struct.Extra1 = Nested{"yy"} 
Struct.Nested.Extra2 = "zz" 

che si tradurrà

{ 
    "Value": "xx", 
    "Value1": "xx", 
    "Extra1": { 
     "Something", "yy" 
    }, 
    "Nest": { 
     "Something": "xx", 
     "Extra2": "zz" 
    } 
} 

Soluzione1: ho pensato di aggiungere omitempty per raggiungere questo obiettivo, ma rende il complesso strutture.

type Struct struct { 
    Value string 
    Value1 string 
    Nest Nested 
    Extra1 Nested `json:"omitempty"` 
} 

type Nested struct { 
    Something string 
    Extra2 string `json:"omitempty"` 
} 

Solution2:

myextras := make(map[string]interface{}) 
// get Struct.Nested in map[string]interface{} format 
myextras = Struct.Nest 
myextras["Extra2"] = "zz" 

// get Struct in map[string]interface{} format 
struct["Nest"] = myextras 
struct["Extra1"] = Nested{"yy"} 

// solves the problem with lots of type casting but doesn't support json tag naming 

Esiste una soluzione migliore per aggiungere elementi annidati, che non sono rappresentate nel struct tipo di dati con il supporto di JSON-tag e potrebbero essere utilizzati per l'uscita per l'utente.

risposta

6

Sulla base di questa risposta:. Can I use MarshalJSON to add arbitrary fields to a json encoding in golang?

Si potrebbe fare qualcosa di simile (demo : http://play.golang.org/p/dDiTwxhoNn):?

package main 

import (
    "encoding/json" 
    "fmt" 
    "log" 
) 

type Book struct { 
    Title string 
    Author string 

    // extra is used for additional dynamic element marshalling 
    extra func() interface{} 
} 

type FakeBook Book 

func (b *Book) SetExtra(fn func() interface{}) { 
    b.extra = fn 
} 

func (b *Book) MarshalJSON() ([]byte, error) { 
    if b.extra == nil { 
     b.extra = func() interface{} { return *b } 
    } 

    return json.Marshal(b.extra()) 
} 

func main() { 
    ms := &Book{ 
     Title: "Catch-22", 
     Author: "Joseph Heller", 
    } 

    ms.SetExtra(func() interface{} { 
     return struct { 
      FakeBook 
      Extra1 struct { 
       Something string `json:"something"` 
      } `json:"extra1"` 
     }{ 
      FakeBook: FakeBook(*ms), 
      Extra1: struct { 
       Something string `json:"something"` 
      }{ 
       Something: "yy", 
      }, 
     } 
    }) 

    out, err := json.MarshalIndent(ms, "", " ") 
    if err != nil { 
     log.Fatalln(err) 
    } 
    fmt.Println(string(out)) 

    mb := &Book{ 
     Title: "Vim-go", 
     Author: "Fatih Arslan", 
    } 

    mb.SetExtra(func() interface{} { 
     return struct { 
      FakeBook 
      Something string `json:"something"` 
     }{ 
      FakeBook: FakeBook(*mb), 
      Something: "xx", 
     } 
    }) 

    out, err = json.MarshalIndent(mb, "", " ") 
    if err != nil { 
     log.Fatalln(err) 
    } 
    fmt.Println(string(out)) 

    mc := &Book{ 
     Title: "Another-Title", 
     Author: "Fatih Arslan", 
    } 

    out, err = json.MarshalIndent(mc, "", " ") 
    if err != nil { 
     log.Fatalln(err) 
    } 
    fmt.Println(string(out)) 
} 
+1

dal momento che la mia modifica perfettamente valida è stata respinta dai mods come "dovrebbe sii un commento "(anche se questo è un enorme spreco di spazio come commento) - nota che non hai bisogno di' json: "-" 'per evitare che la serializzazione sia extra, dal momento che non viene esportato. –

+0

Grazie @NateFinch per le informazioni, ha senso. Lo sto modificando per conto di te. –

2

sì. c'è un tipo json.Raw che non è una struct ma [] byte. puoi gestirlo fuori dalla struttura, in qualsiasi modo maresciallo/unmarsale.

+0

potrebbe fornire il codice per aggiungere ' "EXTRA2"' in formato json.Raw Quello è la parte difficile – Thellimist

2

L'approccio carta è l'unico modo sensato per farlo, tutto il resto (come json.RawMessage campi richiederebbero fase di smistamento in più in ogni caso

Problemi correlati