Ich werde dir einen anderen Ansatz präsentieren, die ich entwickelt habe. Ich denke, es ist viel sauberer. Der einzige Nachteil ist eine etwas komplizierte Objektinitialisierung, aber im Gebrauch ist es sehr gestrafft.
Der wichtigste Punkt ist, dass Sie nicht Ihr JSON-View-Objekt auf dem ursprünglichen Objekt zu stützen und dann Elemente drin, aber andersherum versteckt, sich einen Teil des ursprünglichen Objekts machen:
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"}
Und das ist alles, wenn Sie nur eine Ansicht benötigen, oder wenn Ihre Ansichten schrittweise erweitert werden.
Aber wenn Sie Ihre Ansichten nicht vererbt werden können, werden Sie zu einer Art Mixins greifen müssen, so können Sie von ihnen eine kombinierte Ansicht machen:
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}
}
Hier habe ich eine Ansicht hinzugefügt haben das Objekt in, aber wenn Sie möchten, können Sie es nur schaffen, wenn Marshal
Aufruf:
json.Marshal(ThingVisualView{&obj.ThingBaseMixin, &obj.ThingVisualMixin})
Oder auch ohne vorherige Typdeklaration:
json.Marshal(struct{*ThingBaseMixin;*ThingVisualMixin}{&obj.ThingBaseMixin,&obj.ThingVisualMixin})
Eine Möglichkeit, einen benutzerdefinierten http://golang.org/pkg/encoding/json/#Marshaler zusammen mit einem internen Konfigurationsfeld zu implementieren, ist zu spezifizieren Welche Felder Ihrer Struktur möchten Sie ausgeben? –