~/snippets/go-loop-through-struct-with-reflect
Published on

Loop through a struct with reflect

529 words3 min read
package main

import (
	"fmt"
	"reflect"
)

type Custom struct {
	Wibble string
	Wobble string
}

type AnotherCustom struct {
	Jibble string
	Jobble string
}

type Test struct {
	A []string
	B []int
	C []bool
	D []Custom
	E []AnotherCustom
}

func main() {
	test := &Test{}
	value := reflect.ValueOf(*test)
	t := value.Type()

	for i := 0; i < t.NumField(); i++ {
		ft := t.Field(i).Type // Gives the type []string, []int, []main.Custom etc etc

		ftk := t.Field(i).Type.Kind() // Gives the underlying type - slice

		if t.Field(i).Type.Kind() == reflect.Slice {
			ftek := t.Field(i).Type.Elem().Kind() // What is it a slice of? string, int, struct etc

			// If it's a slice of struct, handle it differently
			if t.Field(i).Type.Elem().Kind() == reflect.Struct {
				fte := t.Field(i).Type.Elem() // What's the struct type? main.Custom, main.AnotherCustom

				// Then loop through the struct fields
				for j := 0; j < t.Field(i).Type.Elem().NumField(); j++ {
					jft := t.Field(i).Type.Elem().Field(j).Type

					fmt.Printf(`======
Field Type: (%v)
Field Type Kind: (%v)
Field Type Element Kind: (%v)
Field Type Element: (%v)
Inner Struct field: (%v)
--------
`, ft, ftk, ftek, fte, jft)
				}

			}

		}
	}
}