【问题标题】:How does golang implement reflection?golang是如何实现反射的?
【发布时间】:2016-01-05 06:23:39
【问题描述】:

使用反射,我们可以得到给定类型(如uint64、用户自定义结构等)的类型名称、存储大小和功能。甚至,我们可以修改给定类型的一些字段。 golang 是如何实现反射的?我猜有以下几种方式:

  1. golang中的每一个类型,包括自定义类型,本身都有类型名、字段名、函数名等信息。 Golang反射只是读取这些信息或者调用函数。

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

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

【问题讨论】:

  • 简单来说,golang反射是如何获取类型的信息的,比如类型名、存储大小、字段、函数等。甚至,反射可以设置值。

标签: reflection go


【解决方案1】:

这只是一个概述,可能不是 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】:

    接口的描述在这里有很好的描述:The Laws of Reflection

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

    基本上,类型是从您的代码中静态获知的。更灵活的接口类型保留原始底层类型,以便返回原始数据类型。

    【讨论】:

    猜你喜欢
    • 2013-12-26
    • 2013-02-12
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    • 2015-12-15
    • 2014-12-30
    • 2013-06-27
    • 1970-01-01
    相关资源
    最近更新 更多