栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Go语言

第003节:通过reflect.Value设置实际变量的值

Go语言 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

reflect.Value是通过reflect.ValueOf(X)获得的,只有当X是指针的时候,才可以通过reflec.Value修改实际变量X的值,即:要修改反射类型的对象就一定要保证其值是“addressable”的。

也就是说:要想修改一个变量的值,那么必须通过该变量的指针地址 , 取消指针的引用 。通过refPtrVal := reflect.Valueof( &var )的方式获取指针类型,你使用refPtrVal.elem( ).set(一个新的reflect.Value)来进行更改,传递给set()的值也必须是一个reflect.value。

这里需要一个方法:


第003节:通过reflect.Value设置实际变量的值

解释起来就是:Elem返回接口v包含的值或指针v指向的值。如果v的类型不是interface或ptr,它会恐慌。如果v为零,则返回零值。

如果你的变量是一个指针、map、slice、channel、Array。那么你可以使用reflect.Typeof(v).Elem()来确定包含的类型。

package mainimport (    "fmt"    "reflect")func main() {    var num float64 = 1.2345    fmt.Println("num的数值:", num)    //需要操作指针    //通过reflect.ValueOf获取num中的reflect.Value,注意,参数必须是指针才能修改其值    pointer := reflect.ValueOf(&num)    newValue := pointer.Elem()    fmt.Println("类型 :", newValue.Type()) //float64    fmt.Println("是否可以修改:", newValue.CanSet())    // 重新赋值    newValue.SetFloat(77)    fmt.Println("新的数值:", num)    ////////////////////    // 如果reflect.ValueOf的参数不是指针,会如何?    //尝试直接修改    //value := reflect.ValueOf(num)    //value.SetFloat(6.28) //panic: reflect: reflect.Value.SetFloat using unaddressable value    //fmt.Println(value.CanSet()) //false    //pointer = reflect.ValueOf(num)    //newValue = value.Elem() // 如果非指针,这里直接panic,“panic: reflect: call of reflect.Value.Elem on float64 Value”}

运行结果:

num的数值: 1.2345类型 : float64是否可以修改: true新的数值: 77

说明

    需要传入的参数是* float64这个指针,然后可以通过pointer.Elem()去获取所指向的Value,注意一定要是指针。如果传入的参数不是指针,而是变量,那么

    通过Elem获取原始值对应的对象则直接panic通过CanSet方法查询是否可以设置返回falsenewValue.CantSet()表示是否可以重新设置其值,如果输出的是true则可修改,否则不能修改,修改完之后再进行打印发现真的已经修改了。reflect.Value.Elem() 表示获取原始值对应的反射对象,只有原始对象才能修改,当前反射对象是不能修改的也就是说如果要修改反射类型对象,其值必须是“addressable”【对应的要传入的是指针,同时要通过Elem方法获取原始值对应的反射对象】struct 或者 struct 的嵌套都是一样的判断处理方式

尝试修改结构体中的字段数值:

package mainimport (    "reflect"    "fmt")type Student struct {    Name string    Age int    School string}func main()  {        s1:=Student{"王二狗",19,"千锋教育"}    fmt.Printf("%Tn",s1) //main.Student    p1:=&s1    fmt.Printf("%Tn",p1) //*main.Student    fmt.Println(s1.Name)    fmt.Println((*p1).Name,p1.Name)    v1:= reflect.ValueOf(&s1) // value    if v1.Kind()==reflect.Ptr{        fmt.Println(v1.Elem().CanSet())        v1 = v1.Elem()    }    f1:=v1.FieldByName("Name")    f1.SetString("韩茹")    f3:=v1.FieldByName("School")    f3.SetString("幼儿园")    fmt.Println(s1)}

运行结果:

main.Student*main.Student王二狗王二狗 王二狗true{韩茹 19 幼儿园}

本文参照:

http://www.sohu.com/a/313420275_657921

https://studygolang.com/articles/12348?fr=sidebar

http://c.biancheng.net/golang/

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/793665.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号