当前位置: 首页 > news >正文

网站手机版济宁高端网站建设

网站手机版,济宁高端网站建设,北京中小企业公司名单,做电影网站需要那种服务器到目前为止#xff0c;反射还只是程序中变量的另一种读取方式。然而#xff0c;在本节中我们将重点讨论如何通过反射机制来修改变量。 回想一下#xff0c;Go语言中类似x、x.f[1]和*p形式的表达式都可以表示变量#xff0c;但是其它如x 1和f(2)则不是变量。一个变量就是一…到目前为止反射还只是程序中变量的另一种读取方式。然而在本节中我们将重点讨论如何通过反射机制来修改变量。 回想一下Go语言中类似x、x.f[1]和*p形式的表达式都可以表示变量但是其它如x 1和f(2)则不是变量。一个变量就是一个可寻址的内存空间里面存储了一个值并且存储的值可以通过内存地址来更新。 对于reflect.Values也有类似的区别。有一些reflect.Values是可取地址的其它一些则不可以。考虑以下的声明语句 x : 2 // value type variable? a : reflect.ValueOf(2) // 2 int no b : reflect.ValueOf(x) // 2 int no c : reflect.ValueOf(x) // x *int no d : c.Elem() // 2 int yes (x) 其中a对应的变量不可取地址。因为a中的值仅仅是整数2的拷贝副本。b中的值也同样不可取地址。c中的值还是不可取地址它只是一个指针x的拷贝。实际上所有通过reflect.ValueOf(x)返回的reflect.Value都是不可取地址的。但是对于d它是c的解引用方式生成的指向另一个变量因此是可取地址的。我们可以通过调用reflect.ValueOf(x).Elem()来获取任意变量x对应的可取地址的Value。 我们可以通过调用reflect.Value的CanAddr方法来判断其是否可以被取地址 fmt.Println(a.CanAddr()) // false fmt.Println(b.CanAddr()) // false fmt.Println(c.CanAddr()) // false fmt.Println(d.CanAddr()) // true 每当我们通过指针间接地获取的reflect.Value都是可取地址的即使开始的是一个不可取地址的Value。在反射机制中所有关于是否支持取地址的规则都是类似的。例如slice的索引表达式e[i]将隐式地包含一个指针它就是可取地址的即使开始的e表达式不支持也没有关系。以此类推reflect.ValueOf(e).Index(i)对应的值也是可取地址的即使原始的reflect.ValueOf(e)不支持也没有关系。 要从变量对应的可取地址的reflect.Value来访问变量需要三个步骤。第一步是调用Addr()方法它返回一个Value里面保存了指向变量的指针。然后是在Value上调用Interface()方法也就是返回一个interface{}里面包含指向变量的指针。最后如果我们知道变量的类型我们可以使用类型的断言机制将得到的interface{}类型的接口强制转为普通的类型指针。这样我们就可以通过这个普通指针来更新变量了 x : 2 d : reflect.ValueOf(x).Elem() // d refers to the variable x px : d.Addr().Interface().(*int) // px : x *px 3 // x 3 fmt.Println(x) // 3 或者不使用指针而是通过调用可取地址的reflect.Value的reflect.Value.Set方法来更新对应的值 d.Set(reflect.ValueOf(4)) fmt.Println(x) // 4 Set方法将在运行时执行和编译时进行类似的可赋值性约束的检查。以上代码变量和值都是int类型但是如果变量是int64类型那么程序将抛出一个panic异常所以关键问题是要确保改类型的变量可以接受对应的值 d.Set(reflect.ValueOf(int64(5))) // panic: int64 is not assignable to int 同样对一个不可取地址的reflect.Value调用Set方法也会导致panic异常 x : 2 b : reflect.ValueOf(x) b.Set(reflect.ValueOf(3)) // panic: Set using unaddressable value 这里有很多用于基本数据类型的Set方法SetInt、SetUint、SetString和SetFloat等。 d : reflect.ValueOf(x).Elem() d.SetInt(3) fmt.Println(x) // 3 从某种程度上说这些Set方法总是尽可能地完成任务。以SetInt为例只要变量是某种类型的有符号整数就可以工作即使是一些命名的类型、甚至只要底层数据类型是有符号整数就可以而且如果对于变量类型值太大的话会被自动截断。但需要谨慎的是对于一个引用interface{}类型的reflect.Value调用SetInt会导致panic异常即使那个interface{}变量对于整数类型也不行。 x : 1 rx : reflect.ValueOf(x).Elem() rx.SetInt(2) // OK, x 2 rx.Set(reflect.ValueOf(3)) // OK, x 3 rx.SetString(hello) // panic: string is not assignable to int rx.Set(reflect.ValueOf(hello)) // panic: string is not assignable to int var y interface{} ry : reflect.ValueOf(y).Elem() ry.SetInt(2) // panic: SetInt called on interface Value ry.Set(reflect.ValueOf(3)) // OK, y int(3) ry.SetString(hello) // panic: SetString called on interface Value ry.Set(reflect.ValueOf(hello)) // OK, y hello 当我们用Display显示os.Stdout结构时我们发现反射可以越过Go语言的导出规则的限制读取结构体中未导出的成员比如在类Unix系统上os.File结构体中的fd int成员。然而利用反射机制并不能修改这些未导出的成员 stdout : reflect.ValueOf(os.Stdout).Elem() // *os.Stdout, an os.File var fmt.Println(stdout.Type()) // os.File fd : stdout.FieldByName(fd) fmt.Println(fd.Int()) // 1 fd.SetInt(2) // panic: unexported field 一个可取地址的reflect.Value会记录一个结构体成员是否是未导出成员如果是的话则拒绝修改操作。因此CanAddr方法并不能正确反映一个变量是否是可以被修改的。另一个相关的方法CanSet是用于检查对应的reflect.Value是否是可取地址并可被修改的 fmt.Println(fd.CanAddr(), fd.CanSet()) // true false
http://www.hkea.cn/news/14480025/

相关文章:

  • html5响应式网站建设平台wordpress解密主题
  • 北京大兴行业网站建设公司网站开发过什么软件
  • 怎么建设一个网站手动修改目录wordpress
  • 眼科医院网站开发网站管理入口
  • 朔州网站建设公司养老网站建设合同
  • 网站设计 成都设计建立企业网站最佳的公司
  • 深圳网站建设比较手机上免费制作ppt的软件
  • 重庆网站建设哪家好网站设计可以吗
  • 构建网站需要会什么浙江网缘电子商务有限公司
  • 扬州市住房和建设局网站canva可画在线设计平台
  • 视频网站空间制作网站代码
  • 单位门户网站可以做百度百科泉州网站建设服务
  • 未央网站建设洛阳建站
  • 淘宝购物券网站怎么做公司网站推广的方法
  • 杭州网站建设第一品牌网站设计文案
  • 网站忧化教程主机如何做网站空间
  • 做网站义乌北仑静态网站建设
  • 合肥公司门户网站制作wordpress 论坛 小程序
  • html 旅游网站庐山市星子网
  • 扁平化颜色网站查关键词排名网
  • asp程序网站后台发布产品的时候前台怎么不显示产品名称网站开发公司创业策划
  • flash 如何做游戏下载网站什么叫界面设计
  • 烟台小学网站建设商城建站
  • 怎样申请做自己的网站网站开发项目报价单
  • 家装业务员怎么做网站营销免费建立个人视频网站
  • 渭南网站建设远景学建网站
  • 丹棱县 网站建设ps软件下载电脑版免费破解版
  • 好品质高端网站设计关键字排名优化工具
  • 网站开发公司团队优势个人网站制作 教程
  • 如何编辑做网站学历提升培训机构