五、Go语言的反射

77 阅读2分钟

反射的性能比较低,如果能避免使用反射,那么一定要替换掉,尤其是会被反复调用的热点代码

在go中,结构体的序列化和反序列化函数MarshalUnmarshal都用到了反射,因此如果追求性能,在序列化比较多的场景,可以考虑使用第三方库easyjson

获取结构体字段有两种方式,一种是FieldByName(按照名字访问),另一种是Field(按照下标访问)。相比于前者,后者的性能要更好一些。

在反射的内部,字段是按顺序存储的,因此按照下标访问查询效率为 O(1),而按照 Name 访问,则需要遍历所有字段,查询效率为 O(N)。结构体所包含的字段(包括方法)越多,那么两者之间的效率差距则越大。

因此,我们可以通过一个map,将对应的名字和下标存储起来,通过map 和 Field()实现FieldByName()的效果,大大提高了效率。

反射的 reflect.New 函数

该函数可以返回一个指向类型未初始化的指针,可以使用该指针来实例化任何类类型的对象。

reflect.New()函数的定义如下:

func New(typ Type) Value

New 函数接收一个 Type 类型的指针,指定要实例化的类型,返回一个 Value 类型值,该值是指向该变量类型的指针,但是并没有初始化该变量的内容。

总的来说,该函数返回的值是指向类型的指针,需要使用Elem()函数来获取该指针指向的值。

在使用反射的时候,可以使用该函数创建一个该类型的新变量,并操作该变量。

参考自:Golang reflect.New() 函数的实例|极客笔记