This is the 17th day of my participation in the August More text Challenge. For details, see:August is more challenging
reflect
The reflection mechanism gets methods and properties dynamically at run time, which can then be manipulated
For example, you can use the reflection mechanism to obtain the field information of the structure, the method information, but also can change the field information, call the method in the structure
type Person struct {
name string
}
// Basic data types
i := 10
f := 3.14
// The basic compound type
a := [3]string {"shaosiming"."dasiming"."tianming"}
s := []int{1.2.3}
m := map[string]int {"shaosiming":18."dasiming":20."tianming":6}
var c chan int
// A custom compound type
p := Person{"shaosiming"}
Copy the code
TypeOf()
func testType(o interface{}) {
Func TypeOf(I interface{}) Type Returns Type: a structure containing some Type information */
t := reflect.TypeOf(o)
The Name function returns the Name of the type, and the Kind() function returns the Name of the class
For basic data types, Name returns the same value as King. For array, slice, map, chan, Name returns null. For struct, Name returns the Name of the structure, and Kind returns struct */
fmt.Println(t, t.Name(), t.Kind())
}
/* Output ~~~~~~~~~ TypeOf ~~~~~~~~~ int int int float64 FLOAT64 FLOAT64 [3] String array []int Slice map[string]int map chan int chan main.Person Person struct */
Copy the code
ValueOf()
func testValue(o interface{}) {
// Return the Value type of the detected object
v := reflect.ValueOf(o)
// Return the value, type and type of the parameter
fmt.Println(v, v.Type(), v.Kind())
}
/* Output ~~~~~~~~~ ValueOf ~~~~~~~~~ 10 int int 3.14 FLOAT64 FLOAT64 [shaosiming dasiming Tianming] [3]string array [1 2 3] []int slice map[dasiming:20 shaosiming:18 tianming:6] map[string]int map
chan int chan {shaosiming} main.Person struct */
Copy the code
CanAddr CanSet
fmt.Println("~~~~~~~~~ CanAddr CanSet ~~~~~~~~~")
o := 10
fmt.Println("Value before modification:", o)
v := reflect.ValueOf(&o).Elem()
// Check whether the address can be obtained
if v.CanAddr() {
fmt.Println("Address available")
// Check whether the value in the address can be changed
if v.CanSet() {
fmt.Println("Modifiable.")
v.SetInt(100)}else {
fmt.Println("Cannot be modified.")}}else {
fmt.Println("Address not available")
}
fmt.Println("Modified value:", o)
Copy the code
reflect struct
// Define the structure
type Student struct {
name string `json:"json_name" ini:"ini_name"`
age int `json:"json_age" ini:"ini_age"`
}
// Structure method
func (s Student) PrintName(a) string {
fmt.Println(s.name)
return s.name
}
// Structure method
func (s Student) PrintAge(a) int {
fmt.Println(s.age)
return s.age
}
// The reflection of the structure
stu := Student{
name: "shaosiming",
age: 18,}Copy the code
Gets the fields of the structure
// Get the list of fields
stuV := reflect.ValueOf(stu)
fmt.Println("~~~~~~~~~ NumField ~~~~~~~~~")
fieldList := stuV.NumField()
fmt.Println("Number of fields:", fieldList)
for i := 0; i < fieldList; i++ {
field := stuV.Field(i)
fmt.Println(field, field.Type(), field.Kind())
}
Copy the code
The method to get the structure
// Get the list of methods
fmt.Println("~~~~~~~~~ NumMethod ~~~~~~~~~")
methodList := stuV.NumMethod()
fmt.Println(Number of methods:, methodList)
for i := 0; i < methodList; i++ {
method := stuV.Method(i)
fmt.Println(method.Type(), method.Kind())
}
Copy the code
Gets the tag of the structure
// Get the tag
stuT := reflect.TypeOf(stu)
fmt.Println(stuT.NumField())
for i := 0; i < stuT.NumField(); i++ {
t := stuT.Field(i)
fmt.Println(t.Tag.Get("json"), t.Tag.Get("ini"))}Copy the code
conclusion
Reflection enhances the flexibility of the language and allows us to write more powerful frameworks, but can make our code very difficult to read if abused. Therefore, the use of reflexes in projects should be limited.