Golang反射机制

Go反射机制:在编译不知道类型的情况下,可更新变量、在运行时查看值、调用方法以及直接对它们的布局进行操作。

为什么使用反射

有时需要封装统一接口对不同类型数据做处理,而这些类型可能无法共享同一个接口,也有可能布局未知,也有可能该类型在程序设计时不存在。
当无法透视一个未知类型的布局时,这段代码就无法继续,所以引入反射机制。

reflect.Type与reflect.Value

Golang反射机制提供两种类型:Type和Value。
Type是一个接口,其中提供很多方法,能够识别类型以及透视类型的组成部分。Value可以包含一个任意类型的值。

reflect.TypeOf

TypeOf函数可以接受任何的interface{}参数,并且把接口中的动态类型以reflect.Type形式返回。TypeOf返回的是实际类型而非接口类型。例如:

  • var w io.Writer = os.Stdout
    fmt.Println(reflect.TypeOf(w))  // os.File
    

reflect.ValueOf

ValueOf函数接受任意的interface{}并将接口的动态值以reflect.Value的形式返回。

  • type User struct {
        Name       string
        Age        int
    }
    
    u := User{"Mike", 32}
    v := reflect.ValueOf(u)
    fmt.Println(v)                          // {Mike, 32}
    

reflect.Type

Type常用方法整理如下:

  • Kind() Kind 获取底层类型

    var w io.Writer = os.Stdout
    fmt.Println(reflect.TypeOf(w))          // os.File
    fmt.Println(reflect.TypeOf(w).Kind())   // struct
    
  • NumField() int 获取结构类型的字段数量,可用于遍历结构

  • Field(i int) StructField 通过下标i获得某一字段项

    type User struct {
    Name       string
    Age        int
    }
    
    u := User{"Mike", 32}
    t := reflect.TypeOf(u)
    
    for i := 0; i < t.NumField(); i++ {
    	fmt.Println(t.Field(i).Name)
    }
    
  • NumMethod() 获得类型的方法集中被导出方法的数量

    for i := 0; i < t.NumMethod(); i++ {
        fmt.Println(t.Method(i).Name)
    }
    

reflect.Value

Value常用方法整理如下:

  • func (v Value) Interface() (i interface{}) 以 interface{} 形式返回v的当前值

    type User struct {
        Name       string
        Age        int
    }
    
    u := User{"Mike", 32}
    v := reflect.ValueOf(u)
    fmt.Println(v.Interface.(User))             // {Mike, 32}
    
  • func (v Value) Kind() Kind 返回v的底层类型

    fmt.Println(v.Kind())                       // struct
    

Type和Value相互转换图示

posted @ 2019-03-15 14:26  waynezly  阅读(161)  评论(0编辑  收藏  举报