反射的基本介绍
反射就是程序在运行时,通过检查其定义的变量以及值,进而找到其对应的真实类型
reflect包
reflect
包实现了运行时反射,允许程序操作任意类型的对象。典型用法是用静态类型interface{}
保存一个值,通过调用TypeOf
获取其动态类型信息,该函数返回一个Type
类型值。调用ValueOf
函数返回一个Value
类型值,该值代表运行时的数据。
reflect.Type和reflect.Value
interface{}
类型变量其具体类型可以使用reflect.Tpye
来表示,而其具体值则使用reflect.Value
来表示
1 | func ValueOf(i interface{}) Value |
ValueOf
返回一个初始化为i
接口保管的具体值的Value
1 | func TypeOf(i interface{}) Type |
TypeOf
返回接口中保存的值的类型
reflect.Kind
reflect
还有一个比较重要的类型Kind
,表示具体类型
1 | func (v Value) Kind() Kind |
Kind
返回v持有的值的分类,如果v
是Value
零值,返回值为Invalid
- Type代表实际类型,如
包名.Student
- Kind代表具体类型,如
struct
- 如果使基本数据类型,Type和Kind相同
NumField()和Field()
1 | func (v Value) NumField() int |
返回v持有的结构体类型值的字段数,如果v
的Kind
不是Struct
会panic
1 | func (v Value) Field(i int) Value |
返回结构体的第i
个字段(的Value
封装)。如果v
的Kind
不是Struct
或i
出界会panic
Elem()
1 | func (v Value) Elem() Value |
Elem
返回v
持有的接口保管的值的Value
封装,或者v
持有的指针指向的值的Value
封装。如果v
的Kind
不是Interface
或Ptr
会panic
1 | func reflectElemTest(i interface{}) { |
Method()和Call()
1 | func (v Value) Method(i int) Value |
返回v
持有值类型的第i
个方法的已绑定(到v
的持有值的)状态的函数形式的Value
封装。如果i
出界,或者v
的持有值是接口类型的零值(ni
l),会panic
。
- 方法排序是按照方法名字进行排序
1 | func (v Value) Call(in []Value) []Value |
Call
方法使用输入的参数in
调用v
持有的函数。例如,如果len(in) == 3
,v.Call(in)
代表调用v(in[0], in[1], in[2])
(其中Value
值表示其持有值)。如果v
的Kind
不是Func
会panic
。它返回函数所有输出结果的Value
封装的切片。如果v
持有值是可变参数函数,Call
方法会自行创建一个代表可变参数的切片,将对应可变参数的值都拷贝到里面。