Go 反射

# 内存结构

Go 自带 GC、反射机制,在内存中的数据结构必然会有额外的数据结构,来记录这些额外的信息。

初探端倪:buildin new 函数(内存分配器 runtime/malloc.go):

alt text

alt text

new 一个变量的时候,实际上编译器会将我们传入的变量转换成 _type 这个结构,mallocgc 函数会分配内存空间,返回结构体的指针。

# 反射机制

假如我们通过反射函数获取当前这个变量的类型。

当前变量的类型信息记录在 kind 这个值内,反射机制只需要简单的找到这个 _type 结构体就可以拿到其属性信息。

其他反射信息同理,只要借助反射包中的逻辑顺藤摸瓜,就会发现别有洞天,比如结构体字段的名字,你只需要探究一下就会发现这个字符串存储在哪里(不再探讨了)。

如何才能拿到这个 _type 信息呢?

# 自己实现一个简易的类型反射函数

alt text

interface 类型数据结构入手。

alt text

alt text

输出:

alt text

# 总结

实际上,反射是编译器帮助我们把各种类型、结构体的 meta 信息存储到一个位置,我们调用反射接口的时候,反射包会去相应的位置查找这些 meta 信息。

反射究竟对性能影响有多大?

反射慢就慢在过程中涉及到大量的变量创建,内存分配是一个很耗费性能的活(看似一个 new 函数很简单,但是逻辑很复杂,逻辑参照 newobject 函数,所以对性能要求较高的场景一般都会使用 sync.poolgin 中的 ctx 就是例子)

反射很好用,该用就用,只有不大量使用(类似于 json 解析里面的那样),性能损耗有限。

你是不是能顿悟出来类型断言的原理了?