golang 反射(reflect)
反射是现代程序必备的元素,用于在 运行时 获取程序元素,如对象等的 元数据,实现动态识别类型及其结构,以及相关的语义信息。
反射在程序中应用非常多,例如:
- 动态生成数据:json 序列化/反序列化; orm 映射, proxy 透明代理对象
- 动态调用方法:plugin 实现
- 框架自动处理程序:annotation tag 注解标签
- 其他需要数据元数据的应用
在必要的场合,灵活应用反射,是中高级程序员能力的评价标准之一。灵活应用的根本是加深对 go 语言编译与实现的理解,并阅读典型应用案例。
滥用反射,也是低中级程序员最常见的问题,造成程序效率底下、不确定性错误增多。
一、Go 中的反射
go 是静态语言,表示内存中任何一个数据对象(data object)的值及其类型必须是编译期可确定的。因此,go 应用运行时不会像 java 等动态语言一样,在运行期维护所有对象的元数据,以支持多态等需要。也不像 c 语言,不提供任何元数据支持。 但注定 go 语言的反射是简单和有限的。
大神文章,必读!必读!必读!在短短的文章中,说明了 go 语言反射的要点!
- The Laws of Reflection 其中文翻译 “反射三法则[https://blog.go-zh.org/laws-of-reflection]”
请使用 $go tool tour
验证该文中所有代码!!!
这里,仅提示其中要点:
类型与接口
- Go是静态类型的语言。每个变量都有一种静态类型
- 有一种重要的类别就是接口类型,它是一组方法的集合
- 向上类型转换(UpCasting)。编译期完成,如果一个数据对象或接口的方法集合包含要转换的类型的方法集合
- 空接口
interface{}
, 它是任何数据都包含的接口
- 接口值(内部表示) - 元组(数据对象的值,数据对象的静态类型)
- 向下类型转换(DownCasting)。 程序通过实现接口断言完成。
接口对象.(断言类型)
- 接口内部的对总是 (值, 具体类型) 的形式,而不会是 (值, 接口类型) 的形式
- 向下类型转换(DownCasting)。 程序通过实现接口断言完成。
反射三法则