Advertisement
Reflection in Golang enables us to inspect types at runtime. It is a form of metaprogramming. It also allows you to inspect, edit, and create variables, functions, and structs at runtime. The Go reflect package provides features for inspecting and manipulating objects at runtime.
Golang’s Reflection is a very useful tool for developers that broadens the scope of any programming language. In Go, reflection is organized around three concepts: types, kinds, and values. The types and functions that support reflection in Go are housed in the reflect package in the standard library.
Golang Reflect TypeOf
The reflect.TypeOf
function returns a value of type reflect.Type
, which represents the type of the variable passed into the TypeOf function.
varType := reflect.TypeOf(var)
This function returns a variable of the type reflect.Type
, which contains methods that provide various pieces of information about the type that defines the variable that was provided.
Example
package main
import (
"fmt"
"reflect"
)
func main() {
num := 10
fmt.Println(reflect.TypeOf(num))
fl := 10.5
fmt.Println(reflect.TypeOf(fl))
str := "Hello World"
fmt.Println(reflect.TypeOf(str))
b := true
fmt.Println(reflect.TypeOf(b))
arr := []int{1, 2, 3}
fmt.Println(reflect.TypeOf(arr))
sarr := [3]int{1, 2, 3}
fmt.Println(reflect.TypeOf(sarr))
kv := map[string]int{"A": 1, "B": 2}
fmt.Println(reflect.TypeOf(kv))
}
Output:
int
float64
string
bool
[]int
[3]int
map[string]int
Go Reflect ValueOf
The reflect.ValueOf
function to create a reflect.Value
instance represents the value of a variable. reflect.Value
can be used to find out information about the value of a variable.
package main
import (
"fmt"
"reflect"
)
func main() {
num := 10
fmt.Println(reflect.ValueOf(num))
fmt.Println(reflect.ValueOf(&num))
fl := 10.5
fmt.Println(reflect.ValueOf(fl))
fmt.Println(reflect.ValueOf(&fl))
str := "Hello World"
fmt.Println(reflect.ValueOf(str))
fmt.Println(reflect.ValueOf(&str))
b := true
fmt.Println(reflect.ValueOf(b))
arr := []int{1, 2, 3}
fmt.Println(reflect.ValueOf(arr))
sarr := [3]int{1, 2, 3}
fmt.Println(reflect.ValueOf(sarr))
kv := map[string]int{"A": 1, "B": 2}
fmt.Println(reflect.ValueOf(kv))
}
Output:
10
0xc00010e018
10.5
0xc00010e060
Hello World
0xc00010c050
true
[1 2 3]
[1 2 3]
map[A:1 B:2]
Reflect Type Name
The Name
method returns the type’s name. Because some types, such as a slice or a pointer, lack names, this function produces an empty string.
num := 10
numType := reflect.TypeOf(num)
fmt.Println(numType.Name())
Output:
int
Reflect Type Kind
The kind method determines whether the type is a slice, a map, a pointer, a struct, an interface, a string, an array, a function, an int, or another primitive type.
num := 10
numType := reflect.TypeOf(num)
fmt.Println("Name: ", numType.Name())
fmt.Println("Kind: ", numType.Kind())
user := User{1, "HTD", 20}
userType := reflect.TypeOf(user)
fmt.Println("Name: ", userType.Name())
fmt.Println("Kind: ", userType.Kind())
Output:
Name: int
Kind: int
Name: User
Kind: struct
For the int variable, the kind and name is same. But for the struct variable, the name of the type is User, while kind is struct.
There are 26 kinds of types in golang.
Reflect Type Elem
The Elem method is used to determine the type contained in a pointer, map, slice, channel, or array.
m := map[string]int{}
tm := reflect.TypeOf(m)
fmt.Println("Name: ", tm.Name())
fmt.Println("Kind: ", tm.Kind())
fmt.Println("Elem Key: ", tm.Key())
fmt.Println("Elem Value: ", tm.Elem())
Output:
Name:
Kind: map
Elem Key: string
Elem Value: int
Golang reflect NumField()
The function reflect.NumField()
returns the number of fields in the provided struct.
The function reflect.Field()
is used to get the name and type of struct fields.
package main
import (
"fmt"
"reflect"
)
type User struct {
Id int
Name string
Age int
Address string
}
func main() {
// user struct
user := User{1, "HTD", 20, "India"}
// get type of user
t := reflect.TypeOf(user)
fmt.Println("Type:", t.Name())
// get kind of user
k := t.Kind()
fmt.Println("Kind:", k)
// get fields of user
fmt.Println("Fields:")
for i := 0; i < t.NumField(); i++ {
f := t.Field(i)
fmt.Printf("%s:%v\n", f.Name, f.Type)
}
}
Output:
Type: User
Kind: struct
Fields:
Id:int
Name:string
Age:int
Address:string
Also, learn: