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