在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
笔者原本是C++开发人员,之前对于反射没太大概念,学了GO之后,才开始接触,在研究了一段时间之后,有了些认识,便整理一个帖子,希望对大家有所帮助。 在学习反射的时候,笔者一直在问自己,反射是什么?为什么要用到反射?它是怎么实现的?笔者觉得,在知道这些问题的答案之后,才算是真正了解反射。下面笔者便从这些问题来着手整理反射。 一、反射是什么? 维基百科上的定义:
《Go 语言圣经》中是这样定义反射的:
通过上面的描述,我们能看出来,反射是“元编程”的一种实现手段,它表现在运行阶段,是对运行代码的一种再编译。 二、反射能干什么? 这里只是针对GO语言的反射来描述,反射主要用在下面两种情况下:
所有的事情都有正反两面,反射也不例外,引入反射之后,会有下面的一些不好的地方:
三、反射是怎么使用的? 在此之前,我们需要先看下,反射的三个定律,如下所示:
定律一:将空接口转换成反射对象 我们通过reflect.Typeof()来显示,真实的对象类型,例子如下:
我们通过reflect.ValueOf()来显示真实对象存储的数值,例子如下所示:
通过MethodByName来获取对应名称的函数,并调用 备注:GetName()原本只是一个返回值,但是输出结果却是[Hello]数组的原因是,Value.Call()函数的返回值是一个[]reflect.Value的数组。 定律二:将反射对象转换成原类型 reflect.ValueOf转换成的反射类型,可以通过Interface方法把它恢复成一个接口值,当然我们可以直接将这个接口值转换成对应的原数据,例子如下所示: 定律三:修改反射对象的值 reflect.ValueOf函数返回的是一份值的拷贝,所以直接对这个值进行修改是无意义的,因为它不会更改原来的那个值。 要想修改原来的数值,需要借用指针的特性,进行修改,这里也就是定律三中提到的可设置性,通过Elem()来找到对应的原数据值。 例子如下所示: 四、反射的原理是什么? 反射的实现是以空接口作为基础的,可以说空的接口是反射实现的基石。空接口类似于C语言中的void*,它可以转换成任何类型的数值。 当我们使用反射特性时,实际上用到的就是存储在 interface 变量中的和类型相关的信息,也就是常说的 <type, value>。 主要涉及到的数据结构和函数如下所示: 五、参考文档: Go语言三大反射定律:https://blog.golang.org/laws-of-reflection Go接口详解:https://zhuanlan.zhihu.com/p/27055513 深度解密Go语言之反射:https://zhuanlan.zhihu.com/p/64884660 灰子学技术: |
请发表评论