dimanche 3 décembre 2017

golang recurisive reflection

I am trying to reflect recursively over a struct, printing out the type of each field. Where a field is an slice of structs, I'd like to be able to identify the type held in the array and then reflect over that type.

Here is some sample code

package main

import (
    "log"
    "reflect"
)

type child struct {
    Name *string
    Age  int
}

type Parent struct {
    Name     string
    Surname  *string
    Children []*child
    PetNames []string
}

func main() {

    typ := reflect.TypeOf(Parent{})
    log.Printf("This is a : %s", typ.Kind())

    for i := 0; i < typ.NumField(); i++ {
        p := typ.Field(i)
        if !p.Anonymous {
            switch p.Type.Kind() {
            case reflect.Ptr:
                log.Printf("Ptr: %s is a type %s", p.Name, p.Type)
            case reflect.Slice:
                log.Printf("Slice: %s is a type %s", p.Name, p.Type)
                subtyp := p.Type.Elem()
                if subtyp.Kind() == reflect.Ptr {
                    subtyp = subtyp.Elem()
                }
                log.Printf("\tDereferenced Type%s", subtyp)
            default:
                log.Printf("Default: %s is a type %s", p.Name, p.Type)
            }
        }
    }

}

The output looks like this:

This is a : struct
Default: Name is a type string
Ptr: Surname is a type *string
Slice: Children is a type []*main.child
    Dereferenced Type main.child
Slice: PetNames is a type []string
    Dereferenced Type string

When I identify that a field type is a slice of pointers, I am able to infer the type by calling subtype.Elem().

The output is 'main.child'

If I then try to reflect child using

subSubType := reflect.TypeOf(subtyp)
log.Printf("%+v", subSubType) 

I get the following:

 *reflect.rtype

How can I use the reflection API to iterate over the fields of the child struct?





Aucun commentaire:

Enregistrer un commentaire