使用反射,我们可以获得类型名称,存储大小和给定类型的函数(例如uint64,用户定义的结构等).甚至,我们可以修改给定类型的某些字段.golang如何实现反思?我想通过以下方式:
golang中的每个类型(包括用户定义的类型)本身都具有类型名称,字段名称和函数名称的信息.Golang反射只是读取这些信息或调用函数.
通过一些机制,Golang可以获得类型名称,存储大小等.类型本身没有这些信息.
我粗略地阅读了golang反射代码.我猜测golang使用了第二种方式.谁能描述反射的具体实现?或者推荐一些文件?阅读所有代码对我来说很难.
这只是一个概述,它可能不是100%准确,但希望你会发现它很有帮助.
在构建时,Go链接器会将有关应用程序使用的所有类型的信息嵌入到可执行文件中(https://github.com/golang/go/blob/master/src/runtime/symtab.go#L39)
每个接口值都包含一个指向数据类型描述符的指针(https://github.com/golang/go/blob/master/src/runtime/type.go#L14)
在从编译时已知的类型转换为接口值的过程中,Go编译器会将此接口值的类型描述符指向具体类型描述符(在编译时已知!).
例如,当你打电话reflect.TypeOf(uint(87))
:
接口值由引用uint
类型描述符的编译器创建
此接口值reflect.TypeOf
作为参数传递给函数
reflect.TypeOf
函数使用链接器在可执行文件中存储的类型描述符来获取有关uint类型的对齐(和其他)信息.