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
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).
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With