2014-06-20 16 views
18

eine Struktur wie so Gegeben:golang - Reflexion über eingebettete structs

type B struct { 
    X string 
    Y string 
} 

type D struct { 
    B 
    Z string 
} 

ich auf D reflektieren möchten und erhalten auf die Felder X, Y, Z.

Intuitiv, bevor die Lösung versucht, Ich nahm an, dass ich in der Lage sein würde, die Struktur D zu durchqueren und alle Felder mit Reflektion zu erhalten (X, Y, Z) und nicht mit B umgehen muss. Aber wie Sie sehen können, sehe ich nur das Embedded Struktur B verwendet Reflexion und nicht seine Felder.

http://play.golang.org/p/qZQD5GdTA8

Gibt es eine Möglichkeit I B vollständig transparent machen kann, wenn sie auf D reflektieren?

Warum möchte ich das?

Imaging eine gemeinsame Struktur (B im Beispiel hier), die in mehreren anderen Strukturen verwendet wird, durch Einbetten. Mit Reflection wird versucht, D in eine andere ähnliche Struktur in einem anderen Paket zu kopieren. Die Zielstruktur zum Kopieren hat alle Attribute flach angelegt (keine Einbettung dort). Es gibt also einen Unterschied zwischen der Quelle und dem Ziel (Einbettung gegen keine Einbettung), aber alle Attribute, die flach angelegt sind, sind gleich. Ich möchte keine benutzerdefinierten Lösungen für jede Struktur erstellen.

Antwort

15

Die von Ihnen erwartete "Transparenz" ist nur syntaktischer Zucker und hat nichts mit der Datendarstellung zu tun. Wenn Sie eine Funktion haben möchten, die Ihre Datenstruktur verflacht, müssten Sie sie selbst schreiben.

Zum Beispiel (On play):

func DeepFields(iface interface{}) []reflect.Value { 
    fields := make([]reflect.Value, 0) 
    ifv := reflect.ValueOf(iface) 
    ift := reflect.TypeOf(iface) 

    for i := 0; i < ift.NumField(); i++ { 
     v := ifv.Field(i) 

     switch v.Kind() { 
     case reflect.Struct: 
      fields = append(fields, DeepFields(v.Interface())...) 
     default: 
      fields = append(fields, v) 
     } 
    } 

    return fields 
} 
+2

vielleicht sollten Sie prüfen, ob das Feld, bevor es zu glätten eingebettet ist, wenn es die ‚Transparenz‘ der OP zu simulieren erwartet? h. "if v.Kind() == reflect.Struct && v.Anonymous {' ' – themihai