io gli presenteremo un altro approccio che ho sviluppato. Penso che sia molto più pulito. L'unico svantaggio è l'inizializzazione degli oggetti leggermente complicata, ma nell'uso è molto snella.
Il punto principale è che non stai basando la tua JSON-view-oggetto per l'oggetto originale e poi nascondere elementi in essa, ma il contrario, che lo rende una parte dell'oggetto originale:
type CommunityBase struct {
Name string
Description string
}
type Community struct {
CommunityBase
FavoriteCount int
Moderators []string
}
var comm = Community{CommunityBase{"Name", "Descr"}, 20, []string{"Mod1","Mod2"}}
json.Marshal(comm)
//{"Name":"Name","Description":"Descr","FavoriteCount":20,"Moderators":["Mod1","Mod2"]}
json.Marshal(comm.CommunityBase)
//{"Name":"Name","Description":"Descr"}
E questo è tutto se hai bisogno di una sola vista, o se le tue opinioni sono gradualmente espanse.
Ma se le vostre opinioni non può essere ereditata, si dovrà ricorrere a una sorta di mixins, in modo da poter fare una visualizzazione combinata da loro:
type ThingBaseMixin struct {
Name string
}
type ThingVisualMixin struct {
Color string
IsRound bool
}
type ThingTactileMixin struct {
IsSoft bool
}
type Thing struct {
ThingBaseMixin
ThingVisualMixin
ThingTactileMixin
Condition string
visualView *ThingVisualView
tactileView *ThingTactileView
}
type ThingVisualView struct {
*ThingBaseMixin
*ThingVisualMixin
}
type ThingTactileView struct {
*ThingBaseMixin
*ThingTactileMixin
}
func main() {
obj := Thing {
ThingBaseMixin: ThingBaseMixin{"Bouncy Ball"},
ThingVisualMixin: ThingVisualMixin{"blue", true},
ThingTactileMixin: ThingTactileMixin{false},
Condition: "Good",
}
obj.visualView = &ThingVisualView{&obj.ThingBaseMixin, &obj.ThingVisualMixin}
obj.tactileView = &ThingTactileView{&obj.ThingBaseMixin, &obj.ThingTactileMixin}
b, _ := json.Marshal(obj)
fmt.Println(string(b))
//{"Name":"Bouncy Ball","Color":"blue","IsRound":true,"IsSoft":false,"Condition":"Good"}
b, _ = json.Marshal(obj.ThingVisualMixin)
fmt.Println(string(b))
//{"Color":"blue","IsRound":true}
b, _ = json.Marshal(obj.visualView)
fmt.Println(string(b))
//{"Name":"Bouncy Ball","Color":"blue","IsRound":true}
b, _ = json.Marshal(obj.tactileView)
fmt.Println(string(b))
//{"Name":"Bouncy Ball","IsSoft":false}
}
Qui ho aggiunto una vista nell'oggetto, ma se vi piace, è possibile creare solo al momento della chiamata Marshal
:
json.Marshal(ThingVisualView{&obj.ThingBaseMixin, &obj.ThingVisualMixin})
o anche senza una dichiarazione di tipo preliminare:
json.Marshal(struct{*ThingBaseMixin;*ThingVisualMixin}{&obj.ThingBaseMixin,&obj.ThingVisualMixin})
.210
Un modo possibile è quello di implementare una consuetudine http://golang.org/pkg/encoding/json/#Marshaler insieme ad un campo di configurazione interna per specificare quali campi della tua struct vuoi emettere –