今天主要来聊聊 Go 语言中反射,希望对你有新的认知
虽然很多人使用 Go 语言有一定时间了,甚至有的使用了 1 年 2 年,然后对于 Go 语言中的反射还是模棱两可,使用起来的时候,心里也不是非常有底气
更有甚者,几乎不使用反射,当然,也不是什么错,在工作中能用最简单最高效,又可扩展,性能还好的方式来进行处理自然是最 nice ,没有必要去生搬硬套一些高级用法,毕竟工作不是我们的试炼场,可以自己下来多多实验,本次就来好好看看如何去玩反射
文章分别从如下五个方面来聊
- 反射是什么
- 反射的规则
- 使用案例并灵活运用
- 反射原理
- 总结
简单来看反射是什么
简单来看,反射就是在程序运行时期对程序本身进行访问和修改的能力,例如在程序运行时,可以修改程序的字段名称,字段值,还可以给程序提供接口访问的信息等等
这是 Go 语言中提供的一种机制,我们可以在 Go 语言公共库中可以看到很多关于 reflect 的使用位置
例如常用的 fmt 包,常用的 json 序列化和反序列化,自然前面我们说到的 gorm 库自然也是使用了反射的
可是我们一般为什么要使用反射呢?
根据反射的能力,自然是因为我们提供的接口并不知道传入的数据类型会是什么样的, 只有当程序运行的时候才知道具体的数据类型
但是我们编码的时候又期望去校验程序运行时传入的类型会是什么样的(例如 json 的序列化)并对其这种具体的数据进行操作,这个时候,咱们就需要用到反射的能力了
所以对于使用到反射的地方,你都能看到 interface{} 是不是就不奇怪了呢?
正是因为不确定传入的数据类型会是什么样的,所以才设计成 interface{} ,那么如果对于 interface 有还不清楚他的特点和使用方式的,可以查看历史文章:
先关注反射的规则
首先关注反射的三个重要的定律,知道规则之后,我们按照规则玩就不会有什么问题,只有当我们不清楚规则,总是触发条款的时候,才会出现奇奇怪怪的问题
- 反射是可以将 接口类型的变量 转换成 反射类型的对象
- 反射可以将 反射类型的对象 转换成 接口类型的变量
- 我们在运行时要去修改的 反射类型的对象 ,那么要求这个对象对应的值是要可写的
对于上述 3 个规则也是比较好理解,还记的之前我们说过的 unsafe 包里面的指针吗?
都是将我们常用的数据类型,转换成包(例如 unsafe包,或者 reflect 包)里面的指定数据类型,然后再按照包里面的规则进行修改数据
相当于,换个马甲,就可以进行不同的操作了
关注使用案例并灵活运用
一般