Reflection interpretation

Reflection in Go language is quite different from other languages. Emission in Golang mainly involves two basic concepts, Type and Value, which are also the two most important types in Reflect package of Go language package.

Reflecting all interfaces in Golang yields an information structure containing Type and Value. As the name implies, Type mainly represents the reflected Type information of the variable itself, while Value represents the information of the variable instance itself.

Function of reflection

Reflection in Golang has two main roles, namely, retrieving type information and retrieving value types.

With reflection we can:

  • The dynamic analysis
  • Function encapsulation
  • .

Reflection gets the data type

Grammar:

reflect.TypeOf(x)

Function:

Get data type

Usage:

Package main import (" FMT ""reflect") func main() {var x = 3.4 var STR =" Hello World" fmt.println ("x type =", reflect.TypeOf(x)) fmt.Println("str type =", reflect.TypeOf(str)) }Copy the code

Reflection fetch Type

Grammar:

reflect.TypeOf(varname)

Function:

You can get the corresponding value of this variable.

Usage:

package main
import (
	"fmt"
	"reflect"
)
func main() {
	var x = 1024
	var str = "Hello World"
	fmt.Println("x type =", reflect.TypeOf(x))
	fmt.Println("str type =", reflect.TypeOf(str))
}

Copy the code

Reflection fetch Type

Grammar:

reflect.TypeOf(varname).Kind()

Function:

We use reflect.typeof to pass in the variable we want to fetch, that is, to get the TypeOf the variable, and the Kind method to get the type details

Usage:

package main
import (
	"fmt"
	"reflect"
)
func main() {
	var x = 1024
	var str = "Hello World"
	typeX := reflect.TypeOf(x)
	typeStr := reflect.TypeOf(str)
	typexKind := typeX.Kind()
	typeStrKind := typeStr.Kind()
	fmt.Println("x type =", typeX, ", Kind =", typexKind)
	fmt.Println("str type =", typeStr, ", Kind =", typeStrKind)
}
Copy the code

Reflection retrieves variable value information

Grammar:

reflect.ValueOf(varname)

Function:

Use reflect.valueof to pass in the variable we want to get, and get the value information for that variable

Usage:

package main
import (
	"fmt"
	"reflect"
)
func main() {
	var x = 1024
	var str = "Hello World"
	valueX := reflect.ValueOf(x)
	valueStr := reflect.ValueOf(str)
	fmt.Println("valueX =", valueX)
	fmt.Println("valueStr =", valueStr)
}
Copy the code

Reflection gets the pointer to which the variable points

Grammar:

reflect.ValueOf(varname).Elem()

Function:

Use reflect.valueof to pass in the variable we want to get, and get the value information for that variable

Usage:

package main
import (
	"fmt"
	"reflect"
)
func main() {
	var x = 1024
	var str = "Hello World"
	valueX := reflect.ValueOf(x)
	valueStr := reflect.ValueOf(str)
	fmt.Println("valueX =", valueX)
	fmt.Println("valueStr =", valueStr)
	valueElemX := valueX.Elem()
	valueElemStr := valueStr.Elem()
	fmt.Println("valueElemX =", valueElemX)
	fmt.Println("valueElemStr =", valueElemStr)
}
Copy the code

Reflection calls the structure method

Grammar:

personValue := reflect.ValueOf(p)
infoFunc := personValue.MethodByName("Info")
infoFunc.Call([]reflect.Value{})
Copy the code

Function:

ValueOf to get the value information of the structure, again using the structure value information MethodByName to get the method of the structure, and finally using the Call method to implement the Call method of the structure

Usage:

import (
    "fmt"
    "reflect"
)
type Student struct {
    Name string
    Age int
    Score float64
}
func (s Student)Info(){
    fmt.Println("Name =", s.Name, "Age =", s.Age, "Score =", s.Score)
}
func main() {
    var p = Student{
        Name:"Jim",
        Age:10,
        Score:99,
    }
    personValue := reflect.ValueOf(p)
    infoFunc := personValue.MethodByName("Info")
    infoFunc.Call([]reflect.Value{})
}
Copy the code

Use a combination of

The following code uses TypeOf to handle the array and time type values contained within the structure. Can be used as a general reflection mode.

Func reflect(o interface{}) error {re := reflect.typeof (o).elem () rv := reflect.valueof (o).elem () // Check whether the structure is if re.Kind() == reflect.Struct { for i := 0; i < re.NumField(); I ++ {f := re.field (I) name := f.namfmt. Printf(" Field name %v :",name) // Get the value of one of the struct fields v := rv.FieldByName(name) if V.type () == reflect.struct {if v.type ().convertibleto (reflect.typeof (time.time {})) {fmt.printf ("field name: %v type of time",name) continue} v.IsNil() { fmt.Printf("field name : If v. type () == reflect.slice {for j := 0; j < v.Len(); If reflect.typeof (v.index (j).interface ()).kind () == reflect.ptr {fmt.printf ("field name: %v type of Ptr" ,name) continue } } } } } return nil }Copy the code

conclusion

Reflection is a useful feature that should be used flexibly, not excessively or thoughtlessly.

If you have any questions or want to know more, you can follow my official accountJim the Superhero, left a message on the official account, I saw the first reply.