Ich habe folgende structs ...Merging zwei ähnliche Strukturen verschiedenen Typen
type Menu struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"`
Description string `protobuf:"bytes,3,opt,name=description" json:"description,omitempty"`
Mixers []*Mixer `protobuf:"bytes,4,rep,name=mixers" json:"mixers,omitempty"`
Sections []*Section `protobuf:"bytes,5,rep,name=sections" json:"sections,omitempty"`
}
Und ...
type Menu struct {
ID bson.ObjectId `json:"id" bson:"_id"`
Name string `json:"name" bson:"name"`
Description string `json:"description" bson:"description"`
Mixers []Mixer `json:"mixers" bson:"mixers"`
Sections []Section `json:"sections" bson:"sections"`
}
Ich brauche im Grunde zwischen den beiden Strukturtypen zu konvertieren, ich habe versuchte, mergo zu verwenden, aber das kann nur Strukturen zusammenführen, die einander zugeordnet werden können. Die einzige Lösung, die ich bisher gefunden habe, besteht darin, durch jede Struktur zu iterieren, die ID zu konvertieren, sie neu zuzuweisen und ihren Typ zwischen string und bson.ObjectId zu konvertieren. Dann durch jedes Kartenfeld iterieren und dasselbe machen. Was sich wie eine ineffiziente Lösung anfühlt.
Ich versuche also, Reflexion zu verwenden, um bei der Konvertierung zwischen den beiden IDs allgemeiner zu sein. Aber ich kann nicht herausfinden, wie ich alle anderen Felder, die automatisch übereinstimmen, effektiv zusammenführen kann, so dass ich mich nur um die Konvertierung zwischen den ID-Typen kümmern kann.
Hier ist der Code, den ich bisher haben ...
package main
import (
"fmt"
"reflect"
"gopkg.in/mgo.v2/bson"
)
type Sub struct {
Id bson.ObjectId
}
type PbSub struct {
Id string
}
type PbMenu struct {
Id string
Subs []PbSub
}
type Menu struct {
Id bson.ObjectId
Subs []Sub
}
func main() {
pbMenus := []*PbMenu{
&PbMenu{"1", []PbSub{PbSub{"1"}}},
&PbMenu{"2", []PbSub{PbSub{"1"}}},
&PbMenu{"3", []PbSub{PbSub{"1"}}},
}
newMenus := Serialise(pbMenus)
fmt.Println(newMenus)
}
type union struct {
PbMenu
Menu
}
func Serialise(menus []*PbMenu) []Menu {
newMenus := []Menu{}
for _, v := range menus {
m := reflect.TypeOf(*v)
fmt.Println(m)
length := m.NumField()
for i := 0; i < length; i++ {
field := reflect.TypeOf(v).Field(i)
fmt.Println(field.Type.Kind())
if field.Type.Kind() == reflect.Map {
fmt.Println("is map")
}
if field.Name == "Id" && field.Type.String() == "string" {
// Convert ID type
id := bson.ObjectId(v.Id)
var dst Menu
dst.Id = id
// Need to merge other matching struct fields
newMenus = append(newMenus, dst)
}
}
}
return newMenus
}
Ich bin nicht nur die Felder manuell neu zuweisen, weil ich hoffe, Karten auf den structs Felder zu erkennen und diese rekursiv durchführen Funktion auf ihnen, aber die Felder werden nicht auf eingebetteten Strukturen identisch sein.
Hoffe das macht Sinn!
[ 'bson.ObjectId'] (http://godoc.org/labix.org/v2/mgo/bson#ObjectId) ist definiert als 'typeObjectId string', damit Sie anstelle von reflection den Typ casting (zu' string') verwenden können. Zur Klarstellung, sind beide Strukturen * gleiche Felder mit unterschiedlichem Typ *, wie in der Frage gezeigt, oder kann es verschiedene Felder haben? Wenn ersteres wahr ist, denke ich, dass Sie die erste Struktur zu JSON marshalieren können und dann die JSON zu der zweiten Struktur unmarshalen. – putu