golang如何实现反射?

17

使用反射,我们可以获取给定类型(如uint64,用户自定义结构等)的类型名称、存储大小和函数。甚至可以修改给定类型的某些字段。 Golang如何实现反射?我猜想以下两种方法:

  1. Golang中的每种类型,包括用户自定义类型,都有有关类型名称、字段名称和函数名称的信息。Golang反射只读取这些信息或调用函数。

  2. 通过某些机制,Golang可以获取类型名称、存储大小等信息。而类型本身并没有这些信息。

我大致阅读了Golang的反射代码。我猜测Golang使用了第二种方法。 谁能描述反射的具体实现方式?或者推荐一些文档?对我来说,阅读所有代码很困难。


简单来说,Golang反射如何获取类型信息,例如类型名称、存储大小、字段、函数等。甚至,反射可以设置值。 - Jianglong Chen
2个回答

9

这只是一个概述,可能不是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类型的对齐(和其他)信息。

2

这里很好地描述了接口: 反射定律.

接口类型的变量存储一对:分配给变量的具体值和该值的类型描述符。

基本上,类型在你的代码中是静态已知的。更灵活的接口类型保留原始底层类型以返回到原始数据类型。


例如,https://play.golang.org/p/KGTz2WscGY 反射机制如何获取uint类型的对齐信息? - Jianglong Chen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接