反射操作普通变量-修改变量值
修改变量值
我们可以通过反射,直接对变量进行修改。主要借助reflect.Value提供的SetXxx方法来进行设置。
但,特别强调:**必须通过对应的指针类型来操作,才能改变传入的变量的值。**
需借助reflect.**Value.Elem() **方法实现。
· func (v Value) SetBool(x bool)
· func (v Value) SetInt(x int64)
· func (v Value) SetUint(x uint64)
· func (v Value) SetFloat(x float64)
· func (v Value) SetComplex(x complex128)
· func (v Value) SetBytes(x []byte)
· func (v Value) SetString(x string)
· func (v Value) SetPointer(x unsafe.Pointer)
· func (v Value) SetCap(n int)
· func (v Value) SetLen(n int)
· func (v Value) SetMapIndex(key, val Value)
首先看这样一个演示案例:
func reflectTest(i interface{}) {
// 得到 reflect.Value
reVal := reflect.ValueOf(i)
// 查看reVal的类别
fmt.Println("kind=", reVal.Kind())
// 修改变量值为 666
reVal.SetInt(666)
}
func main() {
// 定义普遍int 变量
var num int = 100
// 调用反射测试函数,实现修改num的值
reflectTest(&num)
}
在reflect.Value中提供了一个SetInt() 方法。显然可以修改int值num。我们尝试借助该方法,将num的值修改为666。但运行,会报错:
panic: reflect: reflect.Value.SetInt using unaddressable value
借助前面讲到的Kind() 查看reVal的类别,为ptr,说明是一个指针。而默认Value下的所有方法都不是针对指针设定的,而是(v Value)
因此,我们必须在 reVal.SetInt(666) 方法调用之前获取到reVal对应的值,才能正常调用SetInt() 函数。使用reflect.Value.Elem() 方法。
func (v Value) Elem() Value
Elem返回v持有的接口保管的值的Value封装,或者v持有的指针指向的值的Value封装。
添加reflect.Value.Elem() 方法的调用。
// 修改变量值为 666
reVal.Elem().SetInt(666)
打印输出:num = 666。成功修改。
可以按我们以往指针使用的方法来理解Elem() 的作用,reflect.Value.Elem() 方法的调用类似于:
var num int = 100
var p *int = &num
*p = 666
num = *p
fmt.Println("num=", num)
在反射的实际应用中,Elem()方法的出镜率非常高。