The concept of Golang reflection and the transformation of related functions

preface

Let's first look at a problem, the use scenario of reflection

type Monster struct {
	Name string `json:"monster_name"`   -- Reflection mechanism
	Age int `json:"monster_age"`
	Birthday string //....
	Sal float64
	Skill string
}

Use reflection mechanism to write function adapter and bridge connection
The requirements are as follows:
Two anonymous functions are defined

test1 := func(v1 int, v2 int){
t.Log(v1, v2)
test2: = func(v1 int, v2 int, s string){
t.Log(v1, v2, 5)
}

Define an adapter function as a unified processing interface. Its general structure is as follows:

bridge := func(call interface{}, args...interfacef{}){
//content
//Call the function corresponding to test1
bridge(test1,1,2)
//Call the function corresponding to test2
bridge(test2,1,2,"test2")
}
  1. Reflection can dynamically obtain various information of variables at runtime, such as variable type and kind
  2. If it is a structure variable, you can also obtain the information of the structure itself (including the fields and methods of the structure)
  3. Through reflection, you can modify the value of variables and call associated methods.
  4. To use reflection, you need to import ("reflect")

package reflect

import "reflect"

The reflect package implements runtime reflection, allowing programs to manipulate objects of any Type. A typical usage is to hold a Value with the static Type interface {}. Get its dynamic Type information by calling TypeOf. This function returns a Type Value. Calling the ValueOf function returns a Value of Type Value, which represents the data at run time. Zero accepts a Type parameter and returns a Value Type Value representing the zero Value of the Type.
See "The Laws of Reflection" for an introduction to go reflection: http://golang.org/doc/articles/laws_of_reflection.html


func TypeOf

func TypeOf(i interface{}) Type

TypeOf returns the type of the value saved in the interface, and TypeOf(nil) returns nil.

type Type

type Type interface {
    // Kind returns the specific classification of the interface
    Kind() Kind
    // Name returns the type name of the type in its own package. If it is an unnamed type, it will return ""
    Name() string
    // PkgPath returns the package path of type, that is, the import path of the specified package, such as "encoding/base64"
    // If the type is built-in type (string, error) or unnamed type (* T, struct{}, []int), it will return ""
    PkgPath() string
    // Returns a string representation of the type. The string may use a short package name (such as base64 instead of "encoding/base64")
    // There is no guarantee that each Type of string representation is different. If you want to compare whether two types are equal, use the Type comparison directly.
    String() string
    // Returns the number of bytes required to save a value of this type; Similar to unsafe Sizeof
    Size() uintptr
    // Returns the number of bytes that will be aligned when a value of this type is requested from memory
    Align() int
    // Returns the number of bytes that will be aligned when the type is used as a field in the structure
    FieldAlign() int
    // If the type implements the interface represented by u, it will return true
    Implements(u Type) bool
    // If the value of this type can be directly assigned to the type represented by u, return true
    AssignableTo(u Type) bool
    // If the value of this type can be converted to the type represented by u, return true
    ConvertibleTo(u Type) bool
    // Returns the number of words of this type. If the Kind of this type is not Int, Uint, Float or Complex, panic will appear
    Bits() int
    // Returns the length of the array type. If it is not an array type, it will be panic
    Len() int
    // Returns the element type of this type. If the Kind of this type is not Array, Chan, Map, Ptr or Slice, panic will be returned
    Elem() Type
    // Returns the type of the key of type map. If the type is not mapped, it will be panic
    Key() Type
    // Returns the direction of a channel type. If it is not a channel type, it will panic
    ChanDir() ChanDir
    // Returns the number of fields of struct type (the anonymous field is counted as a field). For example, the unstructured type will be panic
    NumField() int
    // Return the type of the ith field of struct type. If it is not a structure or i is not in [0, NumField()), it will be panic
    Field(i int) StructField
    // Returns the type of nested field specified by the index sequence,
    // It is equivalent to calling this method with each value chain in the index. If the unstructured body will panic
    FieldByIndex(index []int) StructField
    // Return the field named name of this type (the anonymous field and its sub fields will be found),
    // Boolean indicating whether it is found. If the unstructured body is found, it will be panic
    FieldByName(name string) (StructField, bool)
    // Returns the field whose first field name satisfies the function match of this type. The Boolean value indicates whether it is found. If the non structure is found, it will panic
    FieldByNameFunc(match func(string) bool) (StructField, bool)
    // If the last input parameter of the function type is "..." IsVariadic returns true as a parameter of form
    // If so, t.In(t.NumIn() - 1) returns the implicit actual type of the parameter (the slice of the declared type)
    // If it is not a function type, it will be panic
    IsVariadic() bool
    // Returns the number of parameters of func type. If it is not a function, it will panic
    NumIn() int
    // Return the type of the ith parameter of func type. If it is not a function or i is not in [0, NumIn()), it will be panic
    In(i int) Type
    // Returns the number of return values of func type. If it is not a function, it will panic
    NumOut() int
    // The type that returns the ith return value of func type. If it is not a function or i is not in [0, NumOut()), it will panic
    Out(i int) Type
    // Returns the number of methods in the method set of this type
    // The method of anonymous field will be calculated; The method of the principal type will shield the method with the same name of the anonymous field;
    // Ambiguity caused by anonymous fields will be filtered out
    NumMethod() int
    // Returns the ith method in the method set of this type. When i is not within the range of [0, NumMethod()), panic will be caused
    // For non interface Type T or * t, the Type field and Func field of the return value describe the unbound function state of the method
    // For the interface Type, the Type field of the return value describes the signature of the method, and the Func field is nil
    Method(int) Method
    // Returns the method in the method set of this type according to the method name, and uses a Boolean value to indicate whether the method is found
    // For non interface Type T or * t, the Type field and Func field of the return value describe the unbound function state of the method
    // For the interface Type, the Type field of the return value describes the signature of the method, and the Func field is nil
    MethodByName(string) (Method, bool)
    // Include hidden or non export methods
}
  1. Type is used to represent a go type.
  2. Not all methods can be used for Type values of all go types. See the documentation for each method for usage restrictions.
  3. When calling a method with classification restrictions, you should first use the Kind method to know the classification of the type. Calling a method that is not supported by this classification will result in panic at run time.

func ValueOf

func ValueOf(i interface{}) Value
  1. ValueOf returns a Value initialized as the specific Value held by the i interface
  2. ValueOf(nil) returns a Value of zero.

type Value

type Value struct {
    // Contains hidden or non exported fields
}
  1. Value provides a reflection interface for the go value. Not all methods can be used for the value representation of all go type values. See the documentation for each method for usage restrictions.
  2. When calling a method with classification restrictions, you should first use the Kind method to know the classification of the value. Calling a method that is not supported by this classification will result in panic at run time.
  3. A zero Value of type Value means that a Value is not held. The IsValid method with zero Value returns false, its Kind method returns Invalid, and the String method returns' ', and all other methods will panic. Most functions and methods never return a Value of zero.
  4. If a function / method returns an illegal Value, its documentation must explicitly describe the specific situation.
  5. If a go type Value can be safely used for multi-threaded concurrent operations, its Value indicates that it can also be safely used for concurrency.
func (v Value) IsValid() bool
func (v Value) IsNil() bool
func (v Value) Kind() Kind
func (v Value) Type() Type
func (v Value) Convert(t Type) Value
func (v Value) Elem() Value
func (v Value) Bool() bool
func (v Value) Int() int64
func (v Value) OverflowInt(x int64) bool
func (v Value) Uint() uint64
func (v Value) OverflowUint(x uint64) bool
func (v Value) Float() float64
func (v Value) OverflowFloat(x float64) bool
func (v Value) Complex() complex128
func (v Value) OverflowComplex(x complex128) bool
func (v Value) Bytes() []byte
func (v Value) String() string
func (v Value) Pointer() uintptr
func (v Value) InterfaceData() [2]uintptr
func (v Value) Slice(i, j int) Value
func (v Value) Slice3(i, j, k int) Value
func (v Value) Cap() int
func (v Value) Len() int
func (v Value) Index(i int) Value
func (v Value) MapIndex(key Value) Value
func (v Value) MapKeys() []Value
func (v Value) NumField() int
func (v Value) Field(i int) Value
func (v Value) FieldByIndex(index []int) Value
func (v Value) FieldByName(name string) Value
func (v Value) FieldByNameFunc(match func(string) bool) Value
func (v Value) Recv() (x Value, ok bool)
func (v Value) TryRecv() (x Value, ok bool)
func (v Value) Send(x Value)
func (v Value) TrySend(x Value) bool
func (v Value) Close()
func (v Value) Call(in []Value) []Value
func (v Value) CallSlice(in []Value) []Value
func (v Value) NumMethod() int
func (v Value) Method(i int) Value
func (v Value) MethodByName(name string) Value
func (v Value) CanAddr() bool
func (v Value) Addr() Value
func (v Value) UnsafeAddr() uintptr
func (v Value) CanInterface() bool
func (v Value) Interface() (i interface{})
func (v Value) CanSet() bool
func (v Value) SetBool(x bool)
func (v Value) SetInt(x int64)
func (v Value) SetUint(x uint64)
func (v Value) SetFloat(x float64)
func (v Value) SetComplex(x complex128)
func (v Value) SetBytes(x []byte)
func (v Value) SetString(x string)
func (v Value) SetPointer(x unsafe.Pointer)
func (v Value) SetCap(n int)
func (v Value) SetLen(n int)
func (v Value) SetMapIndex(key, val Value)
func (v Value) Set(x Value)

Reflection diagram


Variables, interface {} and reflect Values can be converted to each other


Added by iamcaper on Tue, 01 Feb 2022 04:42:11 +0200