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反射实现原理】
推荐阅读
- 200 行 Python 代码实现一个极简 GPT
- 如何使用Go实现原型设计模式
- ChatGPT的打字回复效果,原理是什么?我带你们实现!
- 窦骁|窦骁成功实现阶级跨越,豪门赘婿生活惬意,网友:这软饭太香了
- 跨境电商独立站让你在全球市场上如虎添翼,实现销售逆袭!
- DPI技术如何赋能路由器,实现智加速?
- 如何实现多房间PC远程管理?
- 平凡之路|《平凡之路》:一姐爱情受挫,舒一南实现理想,潘岩人间真实
- 用Go语言实现伪原创,八个技巧分析
- Python 实现栈的几种方式及其优劣