通过反射修改强转值类型_Go 编程:一张图图解释反射

Go语言中文网,致力于每日分享编码、开源等知识,欢迎关注我,会有意想不到的收获!

1. 图解反射

在使用反射之前,此文The Laws of Reflection必读。网上中文翻译版本不少,可以搜索阅读。

开始具体篇幅之前,先看一下反射三原则:

  • Reflection goes from interface value to reflection object.
  • Reflection goes from reflection object to interface value.
  • To modify a reflection object, the value must be settable.

在三原则中,有两个关键词 interface value 与 reflection object。有点难理解,画张图可能你就懂了。

119c07087d0607aa81c4ab393590d4d9.png

先看一下什么是反射对象 reflection object? 反射对象有很多,但是其中最关键的两个反射对象reflection object是:reflect.Type与reflect.Value.直白一点,就是对变量类型与值的抽象定义类,也可以说是变量的元信息的类定义.

再来,为什么是接口变量值 interface value, 不是变量值 variable value 或是对象值 object value 呢?因为后两者均不具备广泛性。在 Go 语言中,空接口 interface{}是可以作为一切类型值的通用类型使用。所以这里的接口值 interface value 可以理解为空接口变量值 interface{} value。

结合图示,将反射三原则归纳成一句话:

通过反射可以实现反射对象 reflection object与接口变量值 interface value之间的相互推导与转化, 如果通过反射修改对象变量的值,前提是对象变量本身是可修改的。

2. 反射的应用

在程序开发中是否需要使用反射功能,判断标准很简单,即是否需要用到变量的类型信息。这点不难判断,如何合理的使用反射才是难点。因为,反射不同于普通的功能函数,它对程序的性能是有损耗的,需要尽量避免在高频操作中使用反射。

举几个反射应用的场景例子:

2.1 判断未知对象是否实现具体接口

通常情况下,判断未知对象是否实现具体接口很简单,直接通过 变量名.(接口名) 类型验证的方式就可以判断。但是有例外,即框架代码实现中检查调用代码的情况。因为框架代码先实现,调用代码后实现,也就无法在框架代码中通过简单额类型验证的方式进行验证。

看看 grpc 的服务端注册接口就明白了。

grpcServer := grpc.NewServer()// 服务端实现注册pb.RegisterRouteGuideServer(grpcServer, &routeGuideServer{})

当注册的实现没有实现所有的服务接口时,程序就会报错。它是如何做的,可以直接查看pb.RegisterRouteGuideServer的实现代码。这里简单的写一段代码,原理相同:

//目标接口定义type Foo interface {Bar(int)} dst := (*Foo)(nil)dstType := reflect.TypeOf(dst).Elem()//验证未知变量 src 是否实现 Foo 目标接口srcType := reflect.TypeOf(src)if !srcType.Implements(dstType) {log.Fatalf("type %v that does not satisfy %v
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值