liveBook · Manning

Type.Field

As explained in Go in Practice, Second Edition

Type.Field is a Go reflect method that returns metadata describing a struct field at a specified index.

Type.Field returns a reflect.StructField describing a struct field at a numeric index. Combine it with Type.NumField to enumerate fields and inspect each field’s name and data type. section 13.1.3

Use the type and value APIs for different parts of reflection:

  • Call Type.NumField to determine the iteration range, then call Type.Field(index) for each field. section 13.1.3
  • Read metadata such as the field name and type from the returned reflect.StructField. section 13.1.3
  • Retrieve the corresponding runtime value with Value.Field using the same index; follow pointer fields with reflect.Indirect when inspecting nested structs. section 13.1.3

Walking a nested struct

A recursive walker examines a Person containing *Name and *Address fields. Type.Field reports fields such as Name with type *main.Name; Value.Field retrieves the matching value, and reflect.Indirect exposes main.Name for further traversal. 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
            }
     }
}

Inspect the recursive walker and its concrete output for primitive values, anonymous structs, and nested pointer-based structs. section 13.1.3

How Go in Practice, Second Edition covers it

How deep it goes
Explains indexed metadata lookup and its relationship to Value.Field, stopping short of broader reflection internals.
Examples
Uses a recursive walker over MyInt, anonymous structs, and Person fields pointing to Name and Address.
What you can do after
Apply via Go's reflect package to enumerate struct fields, inspect metadata, and traverse corresponding nested values.
How it connects
Connects reflect.StructField, Type.NumField, reflect.Value, Value.Field, reflect.Indirect, and structs.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Go in Practice, Second Edition. The section links point to the parts of the book it draws on.