Type.NumField returns the number of fields declared by a struct type. Combined with Type.Field, it supports indexed traversal of a struct’s metadata; the matching index on reflect.Value accesses the corresponding field value. section 13.1.3
A reflection-based struct walker uses Type.NumField in a small sequence:
- Obtain a reflect.Value with reflect.ValueOf and remove a possible pointer with reflect.Indirect. section 13.1.3
- Inspect the value’s type and confirm that its kind is reflect.Struct before enumerating fields. section 13.1.3
- Loop from zero to Type.NumField, then use Type.Field with each index to inspect the field name and data type. section 13.1.3
- Use the same index with Value.Field to obtain the field value, following pointer fields with reflect.Indirect when needed. section 13.1.3
Listing 13.7 Recursively examining a value
func main() {
fmt.Println("Walking a simple integer")
var one MyInt = 1 #1
walk(one, 0) #1
fmt.Println("Walking a simple struct")
two := struct{ Name string }{"foo"} #2
walk(two, 0) #2
fmt.Println("Walking a struct with struct fields") #2
p := &Person{ #3
Name: &Name{"Count", "Tyrone", "Rugen"
},
Address: &Address{"Humperdink Castle",
"Florian"},
}
walk(p, 0)
}
type MyInt int
type Person struct {
Name *Name
Address *Address
}
type Name struct {
Title, First, Last string
}
type Address struct {
Street, Region string
}
func walk(u interface{}, depth int) { #4
val := reflect.Indirect(reflect.ValueOf(u)) #5
t := val.Type() #6
tabs := strings.Repeat("\t", depth+1) #7
fmt.Printf("%sValue is type %q (%s)\n", tabs, t, val.Kind())
if val.Kind() == reflect.Struct { #8
for i := 0; i < t.NumField(); i++ {
field := t.Field(i) #9
fieldVal := reflect.Indirect
(val.Field(i))
tabs := strings.Repeat("\t", depth+2)
fmt.Printf("%sField %q is type %q (%s)\n",
tabs, field.Name, field.Type, fieldVal.Kind())
if fieldVal.Kind() ==
reflect.Struct { #10
walk(fieldVal.Interface(), depth+1) #10
} #10
}
}
}
A recursive walker applies Type.NumField and Type.Field to simple structs and nested pointer-to-struct fields. section 13.1.3
