在Go中获取substruct字段

I am trying to get fields from a struct value using reflection.

package main

import (
    "fmt"
    "reflect"
)

type Vertex struct {
    X         string
    Y         string
    SubVertex SubVertex
}
type SubVertex struct {
    Z string
}

func get_field(v Vertex, field string) string {
    r := reflect.ValueOf(v)
    f := reflect.Indirect(r).FieldByName(field)
    return f.String()
}

func main() {
    v := Vertex{"a", "b", SubVertex{"c"}}

    fmt.Println(get_field(v, "X"))
    fmt.Println(get_field(v, "Y"))
    fmt.Println(get_field(v, "Z"))  // Invalid Value
}

I get Invalid Value in the third case, when I try to get the value of the Z field. If SubVertex were an anonymous field, this would work, but I need to use a named field.

How do I make this work?

In this case, you have to use the reflect package in the same manner as you would accessing the values normally. So

v.X // a
v.Y // b
v.SubVertex.Z // c

becomes

r := reflect.ValueOf(v)
x := reflect.Indirect(r).FieldByName("X")
x.String() // a
...
z := reflect.Indirect(r).FieldByName("SubVertex").FieldByName("Z")
z.String() // c

Note that FieldByName() is called on a Value and returns a Value, so it works much the same as just accessing it regularly. Also note that as per the documentation:

Indirect returns the value that v points to. If v is a nil pointer, Indirect returns a zero Value. If v is not a pointer, Indirect returns v.

So the call to Indirect() would be a No-op, but would protect it from having a meltdown if you decided to give it a pointer in the future.

As for your function, this would work

func get_field(v Vertex, field string) string {
    r := reflect.ValueOf(v)
    if field == "Z" {
        f := reflect.Indirect(r).FieldByName("SubVertex").FieldByName(field)
        return f.String()
    }
    f := reflect.Indirect(r).FieldByName(field)

    return f.String()
}

https://play.golang.org/p/eZyTl8OSTZ