Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Go reflection pkg to get the type of a slice struct field?

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

like image 602
sman Avatar asked Feb 17 '17 09:02

sman


People also ask

How do I use reflection in go?

Reflection in Go is built around three concepts: Types, Kinds, and Values. The reflect package in the standard library is the home for the types and functions that implement reflection in Go. First let’s look at types. You can use reflection to get the type of a variable var with the function call varType := reflect.TypeOf (var).

How to implement run-time reflection in Golang?

Go language provides inbuilt support implementation of run-time reflection and allowing a program to manipulate objects with arbitrary types with the help of reflect package. The reflect.SliceOf () Function in Golang is used to get the slice type with element type t, i.e., if t represents int, SliceOf (t) represents []int.

How to use sliceof () function in Golang?

The reflect.SliceOf () Function in Golang is used to get the slice type with element type t, i.e., if t represents int, SliceOf (t) represents []int. To access this function, one needs to imports the reflect package in the program.

What is the use of package reflect in Java?

Package reflect implements run-time reflection, allowing a program to manipulate objects with arbitrary types. The typical use is to take a value with static type interface {} and extract its dynamic type information by calling TypeOf, which returns a Type. A call to ValueOf returns a Value representing the run-time data.


Video Answer


1 Answers

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

like image 139
icza Avatar answered Oct 26 '22 01:10

icza