一.用反射修改普通变量,以int举例
先看一个简单的主函数 ,修改m
先通过reflect.ValueOf 获得 value ,并看看value 和 value.kind
因为我们是通过 func (v Value) Elem() Value获得 elem 来修改传入的参数。如果v的Kind不是Interface{}或Ptr 会panic;如果v持有的值为nil,会返回Value零值。
这就说明了传入的参数必须是地址的原因,
然后我们利用elem 对传入的参数操作
到这对普通参数的修改已经完成了
这里解释为什么是 elem.SetInt(20) 而不是value.SetInt(20)
因为修改函数 func (v Value) SetInt(x int64) 设置v的持有值。如果v的Kind不是Int、Int8、Int16、Int32、Int64之一或者v.CanSet()返回假,会panic。
而value.kind是 Ptr 。 elem.kind是 int
总的方法:
二. 通过反射对结构体进行操作包括 遍历字段 方法 修改字段方法 调用方法
主函数:
这里定义一个结构体 并给与相应方法与字段
注意反射中的 结构体的字段和 方法首字母要大写!!!!
接下来相同内容不在赘述,看图
取得elem后 下面所有 遍历字段 是对elem进行操作了 原因和上述一样
原因就是 func (v Value)
FieldByName(name string) Value
func (v Value) Field(i int) Value
func (v Value) NumField() int
上述常用方法 都要求 如果v的Kind不是Struct会panic;如果未找到会返回Value零值。
接下来遍历结构体字段和 标签 这里要注意遍历标签是 要通过reflect.TypeOf(i) 来获取标签
修改字段 用elem 原因和上述一样
下面调用结构体方法
注意:结构体方法数量 是和调用NumMethod() 的对象有关的, 当调用对象是value时 会将所有结构体方法都带上 ,而当调用对象是elem 只带上不带(*)的方法
调用时方法时,方法的顺序 是按方法首字母排序的,这里当方法不带参数时,传入nil即可
调用有参方法
这里先加上有参函数 以 func (p person) Cay3(n int,m string) 为例
上面两个Method里的参数不一致 但调出一样的函数的原因 想必你已经懂了
不懂的重看
下面是调用结构体方法所有代码步骤
下面是Go语言的中所有包 及其函数的介绍