TheOriginalAlex
TheOriginalAlex

Reputation: 148

Find struct fields recursively

If I have a struct like this:

var Foo struct {
    Bar struct {
        blah *bool
    }
}

And I send the struct to a function that takes an interface as a parameter, is there an easy way to use reflection to find the field "blah" by name using inVal.FieldByName("blah")?

Upvotes: 0

Views: 788

Answers (1)

Thundercat
Thundercat

Reputation: 121059

Here's one way to do it:

func findField(v interface{}, name string) reflect.Value {
  // create queue of values to search. Start with the function arg.
  queue := []reflect.Value{reflect.ValueOf(v)}
  for len(queue) > 0 {
    v := queue[0]
    queue = queue[1:]
    // dereference pointers
    for v.Kind() == reflect.Ptr {
        v = v.Elem()
    }
    // ignore if this is not a struct
    if v.Kind() != reflect.Struct {
        continue
    }
    // iterate through fields looking for match on name
    t := v.Type()
    for i := 0; i < v.NumField(); i++ {
        if t.Field(i).Name == name {
            // found it!
            return v.Field(i)
        }
        // push field to queue
        queue = append(queue, v.Field(i))
    }
  }
  return reflect.Value{}
}

playground example

Upvotes: 2

Related Questions