1、interface 和 反射
先来看看Golang关于类型设计的一些原则,变量包括(type, value)两部分,理解这一点就知道为什么nil != nil了。
在Golang的实现中,每个interface变量都有一个对应pair,pair中记录了实际变量的值和类型:
(value, type)
value是实际变量值,type是实际变量的类型。一个interface{}类型的变量包含了2个指针,一个指针指向值的类型【对应concrete type】,另外一个指针指向实际的值【对应value】。
2、Golang的反射reflect,reflect的基本功能TypeOf和ValueOf
既然反射就是用来检测存储在接口变量内部(值value;类型concrete type) pair对的一种机制。
reflect.TypeOf()是获取pair中的type,
reflect.ValueOf()获取pair中的value
说明
reflect.TypeOf: 直接给到了我们想要的type类型,如float64、int、各种pointer、struct 等等真实的类型
reflect.ValueOf:直接给到了我们想要的具体的值,如1.2345这个具体数值,或者类似&{1 “Allen.Wu” 25} 这样的结构体struct的值
也就是说明反射可以将“接口类型变量”转换为“反射类型对象”,反射类型指的是reflect.Type和reflect.Value这两种
3、从relfect.Value中获取接口interface的信息
说明
转换的时候,如果转换的类型不完全符合,则直接panic,类型要求非常严格!
转换的时候,要区分是指针还是指
也就是说反射可以将“反射类型对象”再重新转换为“接口类型变量”
eg、pointer := reflect.ValueOf(&num)
value := reflect.ValueOf(num)
convertPointer := pointer.Interface().(*float64)
convertValue := value.Interface().(float64)
4、未知原有类型【遍历探测其Filed】
说明
通过运行结果可以得知获取未知类型的interface的具体变量及其类型的步骤为:
先获取interface的reflect.Type,然后通过NumField进行遍历
再通过reflect.Type的Field获取其Field
最后通过Field的Interface()得到对应的value
通过运行结果可以得知获取未知类型的interface的所属方法(函数)的步骤为:
先获取interface的reflect.Type,然后通过NumMethod进行遍历
再分别通过reflect.Type的Method获取对应的真实的方法(函数)
最后对结果取其Name和Type得知具体的方法名
也就是说反射可以将“反射类型对象”再重新转换为“接口类型变量”
struct 或者 struct 的嵌套都是一样的判断处理方式
代码解析
// 通过接口来获取任意参数,然后一一揭晓
func DoFiledAndMethod