Because of my lack of experience with strongly typed languages, reflection is a concept THAT I really haven’t had much experience with before. Did a search on Wikipedia and explained as follows:
In computer science, reflective programming, or reflection, is the ability of a computer program to access, detect and modify its own state or behavior at runtime. Reflection, figuratively speaking, is the ability of a program to “observe” and modify its behavior as it runs.
Reflection in GO does the same thing, capturing information about the type and value of a variable while the program is running and then accessing or modifying it. The Reflect.typeof () and reflect.valueof () methods are used to retrieve the type and value of a variable.
Reflection type
The TypeOf method returns the type object of the variable from which the type and TypeOf the variable can be obtained.
import (
"fmt"
"reflect"
)
func main(a) {
// Define a variable of type int
var i int = 1
// Get the type object of the variable
var typeOfNum = reflect.TypeOf(i)
// Output type and type
typeOfNumName = typeOfNum.Name()
typeOfNumKind = typeOfNum.Kind()
fmt.Printf("name: %s, kind: %s", typeOfNumName, typeOfNumKind)
}
Copy the code
As you can see, both type and type are int.
Types and categories
Type indicates the type specified when a variable is defined. It can reflect the type defined by the type keyword, and the type is the type to which the variable ultimately belongs. It’s a pale thing to say, but let’s just go to the code.
type num int
// Define a variable of type num
var i num = 1
var typeOfNum = reflect.TypeOf(i)
Copy the code
As you can see, the type is num and the type is int.
For variables that reference types, such as slices, functions, and structs, Kind accurately reflects the underlying type.
func printTypeOf(typeOf reflect.Type) {
fmt.Printf("name: %s, kind: %s\n", typeOf.Name(), typeOf.Kind())
}
type Person struct {}
type IntSlice []int
func main(a) {
var a = IntSlice{}
var b = Person{}
printTypeOf(reflect.TypeOf(a))
printTypeOf(reflect.TypeOf(b))
}
Copy the code
For an anonymous structure or function, the type value is returned as null.
func main(a) {
var a = struct {}{}
printTypeOf(reflect.TypeOf(a))
}
Copy the code
Reflection values
ValueOf method, which can get the ValueOf a variable.
var i = 3.1415926
var s = "Welcome to follow my official account:" Notebook of Natural awakening ""
fmt.Println(reflect.ValueOf(s))
fmt.Println(reflect.ValueOf(i))
Copy the code
Through the reflected value object, can also get the type of variable, and according to its type, can call the corresponding method to get the real value of the variable.
var i = 100
var v = reflect.ValueOf(i)
fmt.Println(v.Int()) // If the value is Int, we can use the Int method to get the specific value
fmt.Println(v.Kind())
Copy the code
Modify the value
The reflected value object can modify the value of the variable itself. First, when fetching a reflection value, you cannot directly fetch the reflection value of a variable, but first fetch the value object of its pointer.
var i = 100
var v = reflect.ValueOf(&i) // Fetch the value object of the pointer to variable I
fmt.Println(v.Kind(), v)
Copy the code
After fetching the value object of the pointer, you cannot immediately assign the value because you get the address of the variable.
To assign, call the Elem method, extract the specific element, and then assign.
var i = 100
var v = reflect.ValueOf(&i) // Fetch the value object of the pointer to variable I
var e = v.Elem()
e.SetInt(500) // Modify the element value
fmt.Println(e.Kind(), i)
Copy the code
Value object and structure
As described earlier, the value of a variable can be obtained by reflection, and the same is true for structures.
type Person struct {
name string
age int
gender string
address string
}
var p = Person{"Shenfq".25."Male"."Changsha, Hunan"}
var v = reflect.ValueOf(p)
fmt.Println(v.Kind(), v)
Copy the code
The reflected value object also provides methods for retrieving information about structure members.
NumField()
NumField() gets the exact number of structure members.
var p = Person{"Shenfq".25."Male"."Changsha, Hunan"}
var v = reflect.ValueOf(p)
fmt.Println("Number of members of the Person structure :", v.NumField())
Copy the code
Field()
Field() retrieves the reflected value of a member of a structure at the specified index position.
var p = Person{"Shenfq".25."Male"."Changsha, Hunan"}
var v = reflect.ValueOf(p)
var num = v.NumField()
for i :=0; i < num; i++ {
var val = v.Field(i)
fmt.Printf("Person[%d]: %s %v\n", i, val.Type(), val)
}
Copy the code
FieldByName()
FieldByName() gets the reflected value of a member of a structure with a specified member name.
var p = Person{"Shenfq".25."Male"."Changsha, Hunan"}
var v = reflect.ValueOf(p)
var vOfName = v.FieldByName("name")
fmt.Printf("Person[name]: %s %v\n", vOfName.Type(), vOfName)
Copy the code