golang反射实现原理( 二 )


package mainimport ("fmt""reflect")type temprature intfunc main() {var temp interface{} = temprature(5)fmt.Printf("temprature is %dn", temp.(temprature))itype := reflect.TypeOf(temp)ivalue := reflect.ValueOf(temp)fmt.Printf("%v: %v", itype, ivalue)}复制
打印出了:

temprature is 5 main.temprature: 5
可以看到,通过 TypeOf 与 ValueOf 方法,我们已经取到了接口变量的类型和实际的值 。
6. golang 反射的实现原理让我们来看一下 TypeOf 与 ValueOf 的实现 。
6.1. TypeOf 源码func TypeOf(i interface{}) Type {eface := *(*emptyInterface)(unsafe.Pointer(&i))return toType(eface.typ)}func toType(t *rtype) Type {if t == nil {return nil}return t}复制
TypeOf 的实现通过 unsafe.Pointer 进行指针类型的强制转换,从而通过返回的实例中获取到内存中数据的实际类型字段 。
6.2. ValueOf 源码func ValueOf(i interface{}) Value {if i == nil {return Value{}}escapes(i)return unpackEface(i)}func escapes(x interface{}) {if dummy.b {dummy.x = x}}func unpackEface(i interface{}) Value {e := (*emptyInterface)(unsafe.Pointer(&i))// NOTE: don't read e.word until we know whether it is really a pointer or not.t := e.typif t == nil {return Value{}}f := flag(t.Kind())if ifaceIndir(t) {f |= flagIndir}return Value{t, e.word, f}}复制
ValueOf 的实现相较于 TypeOf 的实现显得略为复杂一些 。在 unpackEface 函数中,同样通过 unsafe.Pointer 将传入参数转换为了 emptyInterface 类型,从而可以获取到传入参数的类型字段与指向实际数据的指针,最终封装为 Value 类型值返回:
type flag uintptrtype Value struct {typ *rtypeptr unsafe.Pointerflag}复制
这个结构正是 golang 保存任何一个类型变量的存储结构,因此,ValueOf 的返回值可以直接作为变量值来使用 。
7. 后记那么,在实际的使用场景中,反射能够为我们带来哪些便捷的功能呢?敬请期待下一篇文章 — golang 中反射的使用 。

【golang反射实现原理】


推荐阅读