普通的 interface 转 struct 很简单:接口对象后面加上 .(StructType) 即可.
但是复杂一点的,如接口IA的对象a是组合了Stuct A(实现了接口IA)的的Struct AA或者Struct AAA时,想通过接口转“父类”,就麻烦了, 如下:
package main
import (
"fmt"
//"reflect"
)
type IA interface {
Fun()
}
type A struct {
}
func (slf *A) AFun(){
fmt.Println("fun in A")
}
func(slf *A) Fun(){
fmt.Println("xxx")
}
type AA struct {
A
}
type AAA struct {
A
}
type IFun interface {
AFun()
}
func main() {
var a AA
var b AAA
var amap = map[int]IA{}
amap[1] = &a
amap[2] = &b
for _, a :=range amap{
//a.Fun()
a.(*A).AFun()
}
}
编译能通过,但是运行时会报错:
panic: interface conversion: main.IA is *main.AA, not *main.A
如果要用amap里的接口对象调用Struct A的方法 AFun,有什么办法呢?
方法一:
这个最容易想到,就是将AFun添加到IA里。 但是如果不让修改IA呢?
方法二:
就得用到反射了:
av := reflect.ValueOf(a)
av.MethodByName("AFun").Call([]reflect.Value{})
但是反射效率不高
方法三:
type IFun interface {
AFun()
}
for{
a.(IFun).AFun()
}
将AFun添加到其他的接口类型,从而做到既不破坏IA,也不会用到反射。
总结
熟悉interface的话就会知道 interface是由一个方法地址列表和对应数据地址组成的,那么接口转原数据类型,很容易,也很好理解 但是接口转原数据类型中的组合(c++父类)时,编译能通过,估计就是通过反射查找它的组合关系判定合法了,但是运行时,却panic了,这个也好解释:因为运行时进行这种类型转换开销过大,得不偿失。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。