liveBook · Manning

Value.Field

As explained in Go in Practice, Second Edition

Value.Field is a Go reflect method that returns the reflection value of a struct field at a specified index.

Use Value.Field(index) to obtain a struct field's reflect.Value. The index must match the field position returned by Type.Field(index), linking a struct's type metadata to its runtime value. section 13.1.3

A reflective struct walker typically follows this sequence:

  • Convert an interface value with reflect.ValueOf(). section 13.1.3
  • Use reflect.Indirect() when the value may be a pointer. section 13.1.3
  • Iterate field indexes, obtain metadata with Type.Field(), and obtain corresponding values with Value.Field(). 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
            }
     }
}

Follow the recursive walker as it inspects primitive values, simple structs, and pointer-containing nested structs. section 13.1.3

How Go in Practice, Second Edition covers it

How deep it goes
Explains index correspondence and pointer dereferencing, then demonstrates recursive inspection without detailing method internals.
Examples
Uses a recursive walker over MyInt, anonymous structs, and nested Person, Name, and Address values.
What it assumes
Assumes basic Go structs and interfaces while introducing reflect.Value, reflect.Type, field metadata, and pointer handling.
What you can do after
Build reflective struct walkers that retrieve fields and follow pointer fields to their underlying values.
How it connects
Connects reflect.Value to reflect.Type, reflect.StructField, reflect.Indirect, and struct reflection.

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.