反射是什么? 我们平常也是经常用到, 而且这名词都用烂了, 这里就不再详细介绍了.
简单说, 就是有一个不知道是什么类型的变量, 通过反射可以获取其类型, 并可操作属性和方法.
ToStringToStringIntToStringBoolToString
PHP$a$b$a->$b()GolangGolang
希望看完反射的用法之后, 至少以后再看相关代码不至于一脸懵逼. 甚至于需要的时候还能自己手撸一套.
使用Golangreflect
reflect.Typereflect.Value
官方文档地址: reflect.Type reflect.Value
我们在反射中的使用, 也是基于这两个对象的.
对于反射的使用来说, 其实我们在平常使用中, 主要也就用到下面这几种操作, 大部分复杂的操作百年难得一用:
- 变量类型和属性的操作
- 变量方法的操作
下面就基于这两种操作进行简单演示.
变量类型和属性的操作
获取属性信息
reflect.Type
获取类型
uu := &User{}reflect.TypeOf(u).Elem()
ArrayChanMapPtrSlice
KindKind
结构体
数组
Slice
说白了, 数组其实就是一个指向首地址的指针嘛. 故要想获取数组元素的内容, 做一次取值操作就可以啦.
如果数组中存放的是结构体, 在用作结构体处理就好啦
map
获取属性值
reflect.Valuereflect.ValueOf
ValueInterfaceInterface{}
基础类型
GO
结构体
如果是自定义的结构体怎么取值呢? 这, 一直找到基础类型. 因为所有的自定义结构体都是有基础类型组成的嘛.
数组
如果是数组呢? 也很简单
map
MapValueValueMapkeyvalue
属性赋值
reflect.ValueSet
这里注意, 只有指针类型的的变量才能被赋值. 其实很好理解, 值类型在方法调用时是通过复制传值的. 只有传递指针才能够找到原始值的内存地址进行修改.
KindValue
以下所有的赋值操作, 都可以与取值操作联动进行.
基础类型
结构体
Value
需要注意的一点, 结构体只有公共字段才能够通过反射进行赋值, 若赋值给一个私有字段, 会抛出异常.
数组
Set
func (v Value) Set(x Value)
SetValueSet
map
创建空值 Value
NewValueValue
此操作的好处是, 在使用过程中, 完全不需要判断对象类型.
变量方法的操作
普通方法
普通方法指未依附与结构体的方法.
结构体方法
获取方法信息
这里需要注意, 结构体指针和对象所拥有的方法数量是不同的, 具体可看: https://hujingnb.com/archives/348
方法调用