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") }
- Reflection can dynamically obtain various information of variables at runtime, such as variable type and kind
- If it is a structure variable, you can also obtain the information of the structure itself (including the fields and methods of the structure)
- Through reflection, you can modify the value of variables and call associated methods.
- 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 }
- Type is used to represent a go type.
- Not all methods can be used for Type values of all go types. See the documentation for each method for usage restrictions.
- 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
- ValueOf returns a Value initialized as the specific Value held by the i interface
- ValueOf(nil) returns a Value of zero.
type Value
type Value struct { // Contains hidden or non exported fields }
- 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.
- 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.
- 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.
- If a function / method returns an illegal Value, its documentation must explicitly describe the specific situation.
- 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