Go的反射定律

源自官方博客一篇文章《The Laws of Reflection》,主要是对于interface类型和反射的一些概念性定义,以下内容仅用于个人记录,如果没有读过原文可能阅读体验不好,请谅解。

类型与接口

  • go是静态类型语言
  • go是强类型语言
  • 别名类型也必须强转才能赋值类原类型
  • interface类型可以持有任意实现其方法的类型实例的值
  • interface{}其实是含有0个方法的接口类型,可以这样理解,任意类型都实现了0个方法,所以它可以表示任意类型,这是个极端例子
  • 尽管如此,interface{}并不是动态类型

interface类型的表达

强转发生在类型的方法不构成超集子集关系时,目标类型的方法是源类型方法子集时,无需转换。因此任意类型可以不用强转直接转换成interface{},因为它的方法集是空集,是任意方法集合的子集。

interface类型里包含了(值、类型)对儿,但是类型不能是interface类型,简单来说就是禁止套娃。

反射三原则

反射第一条:Reflection goes from interface value to reflection object.
  • 这里有几种类型了:Value、Type、Kind,这一条law就是在讲,反射是把interface类型转换成这些reflect库类型,这个过程叫unpack。简单来说,反射就是对interface中的类型的检查和解构。
  • 两个关键方法,reflect.ValueOf、reflect.TypeOf读取值和值类型
  • TypeOf可以以字符串形式输出类型,与ValueOf().Type()作用一致
  • ValueOf返回值信息,注意不是值本身,取值本身需要使用Float、Int等方法
  • Kind方法返回常量,可用于类型对比,比如Kind() == reflect.Int32
  • reflect.Int无法区分Int和用户自定义的Int别名类型(推测compile阶段会使用原生类型替换掉别名)
反射第二条:Reflection goes from reflection object to interface value
  • reflect.Interface方法可以把reflect.Value类型重新打包成interface类型,这个过程叫pack,simple & easy
反射第三条:To modify a reflection object, the value must be settable
  • Value有一系列setter函数,可以修改interface中的值部分,但是需要interface中的值是【可被寻追的addressable】
  • 因为在reflect.ValueOf的过程中,实际是值拷贝,除非传入指针类型,否则reflect.ValueOf中存储的值,就不是addressable的,这会引发panic
  • Value的Elem方法可以返回另外一个Value,对这个Value的修改,将会直接修改原Value指针指向的地址,当然也必须通过getter/setter方法进行

有关结构体

  • 结构体反射需要通过Elem取得reflect.Value对象,然后通过NumField(获取字段值数目)、Field(获取字段值信息)、Type(获取结构体字段类型信息)等方法/字段,来完善结构体信息
  • 对结构体中的元素修改,通过Field取得值对应Value,通过setter方法修改。需要注意最初传入的结构体对象,依然需要是settable/addressable的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值