去反映字段索引-单个索引与切片

reflect.StructField has an Index field that is typed []int. The documentation on this is slightly confounding:

    Index     []int     // index sequence for Type.FieldByIndex

And of course Type.FieldByIndex follows suit as expected, with the somewhat clearer explanation of its behavior:

    // FieldByIndex returns the nested field corresponding
    // to the index sequence.  It is equivalent to calling Field
    // successively for each index i.
    // It panics if the type's Kind is not Struct.
    FieldByIndex(index []int) StructField

But, there is also Type.Field():

    // Field returns a struct type's i'th field.
    // It panics if the type's Kind is not Struct.
    // It panics if i is not in the range [0, NumField()).
    Field(i int) StructFiel

So the behavior of those respectively is very clear.

My question: Exactly for which fields / what circumstances will a reflect.StructField have an Index with len(field.Index) > 1? Is this there to support enumerating embedded fields (reachable through an anonymous field in the parent)? Does it happen in other cases? (ie. is it safe to assume if !field.Anonymous, then we can just use field.Index[0] as an argument to Field(i int)?)

It can refer to fields in embedded or non embedded structs, recursively:

type Foo struct {
    Bar string
}

type Baz struct {
    Zoo Foo
}

func main() {

    b := Baz{Zoo:Foo{"foo"}}
    v := reflect.ValueOf(b)

    fmt.Println(v.FieldByIndex([]int{0})) //output: <main.Foo Value>

    fmt.Println(v.FieldByIndex([]int{0, 0})) //output: foo

}

Here is an example. To answer this question, I've dig into reflect tests.

package main

import (
    "fmt"
    "reflect"
)

type (
    Bar struct {
        Val string
    }

    Foo struct {
        Bar
    }
)

func main() {
    t := reflect.TypeOf(Foo{})
    f, _ := t.FieldByName("Val")
    fmt.Println(f.Index)         // [0 0]
}