golang learning - reflection

reflection

what is reflection

  • Can be understood as inverse mapping
  • Forward type, value —> object/variable
  • reverse object/variable -> type, value
  • Reflection is the way to obtain type information when the program is running
  • Programmers can use these types of information for more flexible processing, such as:
    • Let static languages ​​have more diverse runtime dynamic features
    • Let the program have introspection ability, so that the flexibility of the interface{} interface object has more room to play
  • The go language provides a reflection package called reflect, which can:
    • Get the Type and Value of the original object
    • Modify the Value value of the original object
    • Dynamically call the method of the original object
    • ……
  • The reflect package implements runtime reflection, allowing programs to manipulate objects of any type . Typical usage is to save a value with static type interface{}, and TypeOfobtain its dynamic type information by calling, and this function returns a Type type value. The calling ValueOffunction returns a value of type Value, which represents the data at runtime. Zero takes a Type parameter and returns a Value representing the zero value of that type.

Related types and methods

func TypeOf

func TypeOf(i interface{}) Type

TypeOfReturns the type of the value stored in the interface, TypeOf(nil)will return nil.

type Type

type Type interface {
    
    //Type 是一个接口
	// Kind返回该接口的具体分类
    Kind() Kind
    
    // Name返回该类型在自身包内的类型名,如果是未命名类型会返回""
    Name() string
    
    // 返回struct类型的字段数(匿名字段算作一个字段),如非结构体类型将panic
    NumField() int
    
    // 返回struct类型的第i个字段的类型,如非结构体或者i不在[0, NumField())内将会panic
    Field(i int) StructField
    
    // 返回该类型的方法集中方法的数目
    // 匿名字段的方法会被计算;主体类型的方法会屏蔽匿名字段的同名方法;
    // 匿名字段导致的歧义方法会滤除
    NumMethod() int
    
    // 返回该类型方法集中的第i个方法,i不在[0, NumMethod())范围内时,将导致panic
    // 对非接口类型T或*T,返回值的Type字段和Func字段描述方法的未绑定函数状态
    // 对接口类型,返回值的Type字段描述方法的签名,Func字段为nil
    Method(int) Method
    /*
    还有其他的方法,暂且省略
    */
}

Kind returns the specific category of the interface
Kind() Kind

Method

func ValueOf

func ValueOf(i interface{
    
    }) Value

ValueOfReturns a Value initialized to the concrete value held by the i interface, ValueOf(nil)returns Value zero.

type Value

type Value struct {
    
    
    // 内含隐藏或非导出字段
}

The Value object has many methods, such as

func (Value)

func (v Value) Type() Type

Returns the Type representation of the type of the value held by v.

func (Value) Int

func (v Value) Int() int64

Returns the signed integer held by v (represented as int64), if v's Kind is not Int、Int8、Int16、Int32、Int64a panic

func (Value) Float

func (v Value) Float() float64

Returns the floating-point number held by v (expressed as float64), if v's Kind is not Float32、Float64a panic

func (Value) NumField

func (v Value) NumField() int

Returns the number of fields of the structure type value held by v, if the Kind of v is not Structa panic

func (Value) Field

func (v Value) Field(i int) Value

Returns the i-th field of the structure (the Value encapsulation). If the Kind of v is not Structor i is out of bounds, it will panic

func (Value) NumMethod

func (v Value) NumMethod() int

Returns the method number of the method set in which v holds a value.

func (Value) Method

func (v Value) Method(i int) Value

Returns a functional encapsulation of Value that is bound (to v's value-holding) state of the ith method of v's holding value type. The return value should not include a receiver when calling the Call method; functions held by the return value always use v's holder as the receiver (i.e., the first argument). If i is out of bounds, or the value held by v is the zero value (nil) of the interface type, it will panic.

func (Value) Interface

func (v Value) Interface() (i interface{})

This method returns the value currently held by v (expressed as/stored in the interface{} type), which is equivalent to:

var i interface{} = (v's underlying value)

If v is obtained by accessing a non-exported structure field, it will cause a panic.

type Kind

type Kind uint

Kind represents the specific classification represented by the value of the Type type. A value of zero indicates an illegal classification.

const (
    Invalid Kind = iota
    Bool
    Int
    Int8
    Int16
    Int32
    Int64
    Uint
    Uint8
    Uint16
    Uint32
    Uint64
    Uintptr
    Float32
    Float64
    Complex64
    Complex128
    Array
    Chan
    Func
    Interface
    Map
    Ptr
    Slice
    String
    Struct
    UnsafePointer
)

type Method

type Method struct {
    
    
    // Name是方法名。PkgPath是非导出字段的包路径,对导出字段该字段为""。
    // 结合PkgPath和Name可以从方法集中指定一个方法。
    // 参见http://golang.org/ref/spec#Uniqueness_of_identifiers
    Name    string
    PkgPath string
    Type  Type  // 方法类型
    Func  Value // 方法的值
    Index int   // 用于Type.Method的索引
}

example

Get the Type and Value of the original object

    package main

    import (
        "fmt"
        "reflect"
    )

    func main() {
    
    
        pi := 3.1415
        t := reflect.TypeOf(pi)  //获取pi的类型信息
        v := reflect.ValueOf(pi) //获取pi的值信息
        if t.Kind() == reflect.Float64 {
    
    
            fmt.Println("Type",t,"value", v.Float())//如果v不是float32或者float64会panic
        }
    }

Type float64 value 3.1415

compare type with kind

    package main

    import (
        "fmt"
        "reflect"
    )

    type people struct{
    
    
        name string 
        age int
    }
    func main() {
    
    
        pi := 3.1415
        p :=people{
    
    "kyl",18}
        t := reflect.TypeOf(pi)  
        v := reflect.ValueOf(pi)
        if t.Kind() == reflect.Float64 {
    
    
            fmt.Println("Type",t,"value", v.Float(),"kind",v.Kind())
        }
        t=reflect.TypeOf(p)
        v=reflect.ValueOf(p)
        fmt.Println("Type",t,"value",v,"Kind",t.Kind())
    }

Type float64 value 3.1415 kind float64
Type main.people value {kyl 18} Kind struct

It can be seen that type is not exactly the same as kind, especially in custom types

Get structure content and method information

    package main

    import (
        "fmt"
        "reflect"
    )

    type student struct {
    
    
        ID    int
        Name  string
        Sex   bool
        Grade float32
    }

    func (s student) Myname() {
    
    
        fmt.Println("my name is", s.Name)
    }

    func (s student) Sayhi() {
    
    
        fmt.Println("hi nice to meet you!")
    }

    func structinfo(o interface{
    
    }) {
    
     //可以传入任何结构类型的对象
        t := reflect.TypeOf(o)
        if k := t.Kind(); k != reflect.Struct {
    
    
            fmt.Println("not a struct")
            return
        }
        fmt.Println("struct name is", t.Name())
        fmt.Println("fields of struct is:")
        v := reflect.ValueOf(o)
        for i := 0; i < t.NumField(); i++ {
    
    
            fmt.Println(t.Field(i).Type, ":", v.Field(i).Interface())
        }
        fmt.Println("Methods of struct is:")
        for i:=0;i<t.NumMethod();i++{
    
    
            fmt.Println(t.Method(i).Name,":",t.Method(i).Type,v.Method(i))//只能反射公有的方法
        }
    }
    func main() {
    
    
        stu := student{
    
    1, "kyl", true, 96.5}
        structinfo(stu)
    }

struct name is student fields of struct is: int : 1 string : kyl bool : true float32 : 96.5 Methods of struct is: Myname : func(main.student) 0x48c4e0 Sayhi : func(main.student) 0x48c4e0

Guess you like

Origin blog.csdn.net/jinniulema/article/details/119102960