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常用方法整理如下:
1 Kind() Kind 获取底层类型
var w io.Writer = os.Stdout fmt.Println(reflect.TypeOf(w)) // os.File fmt.Println(reflect.TypeOf(w).Kind()) // struct
2 NumField() int 获取结构类型的字段数量,可用于遍历结构
3 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) }
4 NumMethod() 获得类型的方法集中被导出方法的数量
for i := 0; i < t.NumMethod(); i++ { fmt.Println(t.Method(i).Name) }
-
reflect.Value
Value常用方法整理如下:
1 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}
2 func (v Value) Kind() Kind 返回v的底层类型
fmt.Println(v.Kind()) // struct
-
Type和Value相互转换图示