2014-06-20 28 views
18

Attribuite una struttura in questo modo:golang - riflessione sulla struct incorporati

type B struct { 
    X string 
    Y string 
} 

type D struct { 
    B 
    Z string 
} 

voglio riflettere su D e raggiungere i campi X, Y, Z.

Intuitivamente, prima di tentare la soluzione, Supponevo che sarei stato in grado di attraversare la struttura D e ottenere tutti i campi usando la riflessione (X, Y, Z) e non dovrei occuparmi di B.

Ma come puoi vedere, vedo solo l'embedded struct B usando reflection e non i suoi campi.

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

C'è un modo per rendere B completamente trasparente quando riflette sulla D?

Perché lo voglio?

Immagine di una struttura comune (B nell'esempio qui), utilizzata in più altre strutture mediante l'incorporamento. Usando reflection, il tentativo è di copiare D in un'altra struttura simile in un pacchetto diverso. La struttura di destinazione per la copia avrà tutte le caratteristiche disposte in modo piatto (nessuna incorporazione). Quindi c'è una discrepanza tra la sorgente e la destinazione (incorporamento o assenza di incorporamento), ma tutti gli attributi presentati in modo piatto sono gli stessi. Non voglio creare soluzioni personalizzate per ogni struttura.

risposta

15

La "trasparenza" che ci si aspetta è solo zucchero sintattico e non ha nulla a che fare con la rappresentazione dei dati. Se vuoi avere una funzione che appiattisce la struttura dei tuoi dati, dovresti scriverla da solo.

Per esempio (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

forse si dovrebbe verificare se il campo è incorporato, prima di appiattire se è per simulare la 'trasparenza' del PO si aspetta? Ad esempio, se v.Kind() == reflect.Struct && v.Anonimo {'' – themihai

Problemi correlati