Golang Tutorial
Introduction Variables Constants Data Type Convert Types Operators If..Else Switch..Case For Loops Functions Variadic Functions Deferred Functions Calls Panic and Recover Arrays Slices Maps Struct Interface Goroutines Channels Concurrency Problems Logs Files and Directories Reading and Writing Files Regular Expression Find DNS records Cryptography Gotchas in Golang Import and Export Best Golang Packages Web Application Goroutines and Channels Exercises Reflection in Golang Golang for beginners Strings in Golang HTTP Client Server Examples Context PackageGolang Reference
Basic Programs Advance Programs Data Structure and Algorithms Date and Time Slice Sort, Reverse, Search Functions String Functions Methods and Objects Interface TypeBeego Framework
Beego Setup Beego Database Migration Beego GET POST Beego RoutingReflection in Golang
Reflection
Reflection in Go is a form of metaprogramming. Reflection allows us to examine types at runtime. It also provides the ability to examine, modify, and create variables, functions, and structs at runtime. The Go reflect package gives you features to inspect and manipulate an object at runtime. Reflection is an extremely powerful tool for developers and extends the horizon of any programming language. Types, Kinds and Values are three important pieces of reflection that are used in order to find out information.
reflect.Copy() Function of Reflect Package
Copy copies the contents of source into destination until either destination has been filled or source has been exhausted. It returns the number of elements copied. Destination and source each must have kind Slice or Array, and destination and source must have the same element type.
Example
package main
import (
"fmt"
"reflect"
)
func main() {
destination := reflect.ValueOf([]string{"A", "B", "C"})
source := reflect.ValueOf([]string{"D", "E", "F"})
// Copy() function is used and it returns the number of elements copied
counter := reflect.Copy(destination, source)
fmt.Println(counter)
fmt.Println(source)
fmt.Println(destination)
}
Output
3
[D E F]
[D E F]
reflect.DeepEqual() Function of Reflect Package
DeepEqual returns True or False whether x and y are "deeply equal" or not. Array values are deeply equal when their corresponding elements are deeply equal. Struct values are deeply equal if their corresponding fields, both exported and un-exported, are deeply equal. Slice values are deeply equal when (they are both nil or both non-nil, they have the same length, and either they point to the same initial entry of the same underlying array).
Example
package main
import (
"fmt"
"reflect"
)
type mobile struct {
price float64
color string
}
func main() {
// DeepEqual is used to check two slices are equal or not
s1 := []string{"A", "B", "C", "D", "E"}
s2 := []string{"D", "E", "F"}
result := reflect.DeepEqual(s1, s2)
fmt.Println(result)
// DeepEqual is used to check two arrays are equal or not
n1 := [5]int{1, 2, 3, 4, 5}
n2 := [5]int{1, 2, 3, 4, 5}
result = reflect.DeepEqual(n1, n2)
fmt.Println(result)
// DeepEqual is used to check two structures are equal or not
m1 := mobile{500.50, "red"}
m2 := mobile{400.50, "black"}
result = reflect.DeepEqual(m1, m2)
fmt.Println(result)
}
Output
false
true
false
reflect.Swapper() Function of Reflect Package
Swapper function is used to swaps the elements in the provided slice. You can use this function in trick way to reverse or sort the slice also.
Example
package main
import (
"fmt"
"reflect"
)
func main() {
theList := []int{1, 2, 3, 4, 5}
swap := reflect.Swapper(theList)
fmt.Printf("Original Slice :%v\n", theList)
// Swapper() function is used to swaps the elements of slice
swap(1, 3)
fmt.Printf("After Swap :%v\n", theList)
// Reversing a slice using Swapper() function
for i := 0; i < len(theList)/2; i++ {
swap(i, len(theList)-1-i)
}
fmt.Printf("After Reverse :%v\n", theList)
}
Output
Original Slice :[1 2 3 4 5]
After Swap :[1 4 3 2 5]
After Reverse :[5 2 3 4 1]
reflect.TypeOf() Function of Reflect Package
The reflect.TypeOf function returns a value of type reflect.Type, which represents the type of the variable passed into the TypeOf function.
Example
package main
import (
"fmt"
"reflect"
)
func main() {
v1 := []int{1, 2, 3, 4, 5}
fmt.Println(reflect.TypeOf(v1))
v2 := "Hello World"
fmt.Println(reflect.TypeOf(v2))
v3 := 1000
fmt.Println(reflect.TypeOf(v3))
v4 := map[string]int{"mobile": 10, "laptop": 5}
fmt.Println(reflect.TypeOf(v4))
v5 := [5]int{1, 2, 3, 4, 5}
fmt.Println(reflect.TypeOf(v5))
v6 := true
fmt.Println(reflect.TypeOf(v6))
}
Output
[]int
string
int
map[string]int
[5]int
bool
reflect.ValueOf() Function of Reflect Package
The reflect.ValueOf function to create a reflect.Value instance that represents the value of a variable. reflect.Value has methods for finding out information about the value of a variable.
Example
package main
import (
"fmt"
"reflect"
)
func main() {
v1 := []int{1, 2, 3, 4, 5}
fmt.Println(reflect.ValueOf(v1))
v2 := "Hello World"
fmt.Println(reflect.ValueOf(v2))
v3 := 1000
fmt.Println(reflect.ValueOf(v3))
fmt.Println(reflect.ValueOf(&v3))
v4 := map[string]int{"mobile": 10, "laptop": 5}
fmt.Println(reflect.ValueOf(v4))
v5 := [5]int{1, 2, 3, 4, 5}
fmt.Println(reflect.ValueOf(v5))
v6 := true
fmt.Println(reflect.ValueOf(v6))
}
Output
[1 2 3 4 5]
Hello World
1000
0xc0000a00b8
map[laptop:5 mobile:10]
[1 2 3 4 5]
true
reflect.NumField() Function of Reflect Package
The reflect.NumField() Function returns the number of fields in the given struct
Example
package main
import (
"fmt"
"reflect"
)
type T struct {
A int
B string
C float64
D bool
}
func main() {
t := T{10, "ABCD", 15.20, true}
typeT := reflect.TypeOf(t)
fmt.Println(typeT.NumField())
}
Output
4
reflect.Field() Function of Reflect Package
The reflect.Field() Function is used to access the name and type of struct fields.
Example
package main
import (
"fmt"
"reflect"
)
type T struct {
A int
B string
C float64
D bool
}
func main() {
t := T{10, "ABCD", 15.20, true}
typeT := reflect.TypeOf(t)
for i := 0; i < typeT.NumField(); i++ {
field := typeT.Field(i)
fmt.Println(field.Name, field.Type)
}
}
Output
A int
B string
C float64
D bool
reflect.FieldByIndex() Function of Reflect Package
The reflect.FieldByIndex() Function is used to get the nested field corresponding to index.
Example
package main
import (
"fmt"
"reflect"
)
type First struct {
A int
B string
C float64
}
type Second struct {
First
D bool
}
func main() {
s := Second{First: First{10, "ABCD", 15.20}, D: true}
t := reflect.TypeOf(s)
fmt.Printf("%#v\n", t.FieldByIndex([]int{0}))
fmt.Printf("%#v\n", t.FieldByIndex([]int{0, 0}))
fmt.Printf("%#v\n", t.FieldByIndex([]int{0, 1}))
fmt.Printf("%#v\n", t.FieldByIndex([]int{0, 2}))
fmt.Printf("%#v\n", t.FieldByIndex([]int{1}))
}
Output
reflect.StructField{Name:"First", PkgPath:"", Type:(*reflect.rtype)(0x4bda40), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:true}
reflect.StructField{Name:"A", PkgPath:"", Type:(*reflect.rtype)(0x4ad800), Tag:"", Offset:0x0, Index:[]int{0}, Anonymous:false}
reflect.StructField{Name:"B", PkgPath:"", Type:(*reflect.rtype)(0x4adf80), Tag:"", Offset:0x8, Index:[]int{1}, Anonymous:false}
reflect.StructField{Name:"C", PkgPath:"", Type:(*reflect.rtype)(0x4ad400), Tag:"", Offset:0x18, Index:[]int{2}, Anonymous:false}
reflect.StructField{Name:"D", PkgPath:"", Type:(*reflect.rtype)(0x4ad200), Tag:"", Offset:0x20, Index:[]int{1}, Anonymous:false
reflect.FieldByName() Function of Reflect Package
The reflect.FieldByName() Function in Golang is used to get ands set the struct field value by given field name.
Example
package main
import (
"fmt"
"reflect"
)
type T struct {
A int
B string
C float64
}
func main() {
s := T{10, "ABCD", 15.20}
fmt.Println(reflect.ValueOf(&s).Elem().FieldByName("A"))
fmt.Println(reflect.ValueOf(&s).Elem().FieldByName("B"))
fmt.Println(reflect.ValueOf(&s).Elem().FieldByName("C"))
reflect.ValueOf(&s).Elem().FieldByName("A").SetInt(50)
reflect.ValueOf(&s).Elem().FieldByName("B").SetString("Test")
reflect.ValueOf(&s).Elem().FieldByName("C").SetFloat(5.5)
fmt.Println(reflect.ValueOf(&s).Elem().FieldByName("A"))
fmt.Println(reflect.ValueOf(&s).Elem().FieldByName("B"))
fmt.Println(reflect.ValueOf(&s).Elem().FieldByName("C"))
}
Output
10
ABCD
15.2
50
Test
5.5
reflect.MakeSlice() Function of Reflect Package
MakeSlice creates a new zero-initialized slice value for the specified slice type, length, and capacity.
Example
package main
import (
"fmt"
"reflect"
)
func main() {
var str []string
var strType reflect.Value = reflect.ValueOf(&str)
newSlice := reflect.MakeSlice(reflect.Indirect(strType).Type(), 10, 15)
fmt.Println("Kind :", newSlice.Kind())
fmt.Println("Length :", newSlice.Len())
fmt.Println("Capacity :", newSlice.Cap())
}
Output
Kind : slice
Length : 10
Capacity : 15
reflect.MakeMap() Function of Reflect Package
MakeMap creates a new map with the specified type.
Example
package main
import (
"fmt"
"reflect"
)
func main() {
var str map[string]string
var strType reflect.Value = reflect.ValueOf(&str)
newMap := reflect.MakeMap(reflect.Indirect(strType).Type())
fmt.Println("Kind :", newMap.Kind())
}
Output
Kind : map
reflect.MakeChan() Function of Reflect Package
MakeChan creates a new channel with the specified type and buffer size.
Example
package main
import (
"fmt"
"reflect"
)
func main() {
var str chan string
var strType reflect.Value = reflect.ValueOf(&str)
newChannel := reflect.MakeChan(reflect.Indirect(strType).Type(), 512)
fmt.Println("Kind :", newChannel.Kind())
fmt.Println("Capacity :", newChannel.Cap())
}
Output
Kind : chan
Capacity : 512
reflect.MakeFunc() Function of Reflect Package
The reflect.MakeFunc() Function is used to get the new function of the given Type that wraps the function fn.
Example
package main
import (
"fmt"
"reflect"
)
type Sum func(int64, int64) int64
func main() {
t := reflect.TypeOf(Sum(nil))
mul := reflect.MakeFunc(t, func(args []reflect.Value) []reflect.Value {
a := args[0].Int()
b := args[1].Int()
return []reflect.Value{reflect.ValueOf(a + b)}
})
fn, ok := mul.Interface().(Sum)
if !ok {
return
}
fmt.Println(fn(5, 6))
}
Output
11