2015-07-17 12 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"` 
} 

Chcę dodać elementy, które nie są w definicjach structs bez tworzenia innego typu struct. Na przykładGolang modyfikować json bez struktury

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

co spowoduje

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

Porada1: myślałem dodawania omitempty do osiągnięcia tego celu, ale to sprawia, że ​​kompleks elemencie.

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 

Czy istnieje lepsze rozwiązanie, aby dodać elementy zagnieżdżone, które nie są reprezentowane w struct typu danych ze wsparciem json-tag i mogą być wykorzystane do produkcji do użytkownika.

Odpowiedz

6

Na podstawie tej odpowiedzi:. Can I use MarshalJSON to add arbitrary fields to a json encoding in golang?

mógłby zrobić coś podobnego (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

Ponieważ mój całkowicie poprawny edycja została odrzucona przez modów jak „powinien być komentarzem "(mimo że jest to ogromne marnowanie miejsca jako komentarz) - zauważ, że nie potrzebujesz' json: "-" ', aby zapobiec dodatkowemu serializowaniu, ponieważ nie jest on eksportowany. –

+0

Dzięki @NateFinch dla informacji, ma sens. Edytuję to w imieniu Ciebie. –

2

tak. istnieje typ json.Raw, który nie jest strukturą, ale [] bajtem. możesz nim zarządzać z poziomu struktury, w dowolny sposób marshal/nonmarshal.

+0

można podać kod, aby dodać '„extra2”' w formacie json.Raw Ów udział trudne – Thellimist

2

Podejście mapa jest jedyny rozsądny sposób to zrobić, wszystko inne (jak json.RawMessage pola wymagałoby dodatkowego etapu rozrządowej w każdym razie

Powiązane problemy