简体   繁体   中英

How to use Golang Reflection to get the type of a struct field that is a slice?

I'm trying to use reflection to build a routine that will list the Name, Kind and Type of all fields in an arbitrary struct that gets passed in. Here is what I've got so far:

type StatusVal int
type Foo struct {
    Name string
    Age  int
}
type Bar struct {
    Status StatusVal
    FSlice []Foo
}

func ListFields(a interface{}) {
    v := reflect.ValueOf(a).Elem()
    for j := 0; j < v.NumField(); j++ {
        f := v.Field(j)
        n := v.Type().Field(j).Name
        t := f.Type().Name()
        fmt.Printf("Name: %s  Kind: %s  Type: %s\n", n, f.Kind(), t)
    }
}

func main() {
    var x Bar
    ListFields(&x)
}

The output is as follows:

Name: Status  Kind: int  Type: StatusVal
Name: FSlice  Kind: slice  Type: 

When the field is a slice, the type is blank. I tried several ways to get the slice's data type, but all attempts resulted in a panic... usually this one:

reflect: call of reflect.Value.Elem on slice Value

What changes need to be made to this code so that the type for all fields, including slices, will be listed in the output?

Here's the playground link: https://play.golang.org/p/zpfrYkwvlZ

A slice type given in a type literal like []Foo is an unnamed type, hence Type.Name() returns an empty string "" .

Use Type.String() instead:

t := f.Type().String()

And then the output (try it on the Go Playground ):

Name: Status  Kind: int  Type: main.StatusVal
Name: FSlice  Kind: slice  Type: []main.Foo

See related question to know more about types and their names: Identify non builtin-types using reflect

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM