答案 0 :(得分:2)
如果你有一个嵌入式结构和阴影,你总是可以得到该字段,好像它是一个与嵌入式结构的类型同名的成员变量,这由你的行bATest()显示。
那我们该怎么办?使用reflect.Value.FieldByName获取字段。根据您的确切设置,它有点笨拙。您不能在指向结构的指针上使用FieldByName。
package main
import (
"fmt"
"reflect"
)
type A struct{}
type B struct {
A
}
func (self *A) Test() {
fmt.Println("I'm A")
}
func (self *B) Test() {
fmt.Println("I'm B")
}
func main() {
b := &B{}
b.Test()
b.A.Test()
val := reflect.ValueOf(b)
subVal := val.Elem().FieldByName("A").Addr()
subVal.MethodByName("Test").Call([]reflect.Value{})
val.MethodByName("Test").Call([]reflect.Value{})
}
如图所示,它有点难看。您首先需要调用Elem
来获取值val
,然后获取字段,然后获取指向该字段的指针,因为A.Test
实际上在(*A)
上,并且不是A
。虽然Go指针通常是透明的,但遗憾的是它并不适用于反射,所以你必须自己做所有明确的寻址/解除引用,但如果你理解了指针,它就非常简单。
答案 1 :(得分:2)
当你将一个结构体嵌入到另一个体系结构中时,比如说A进入B,你只是在结构B中创建了一个名为A的类型A的字段。为了方便语法,你可以直接在B上调用A上的方法,但是语义上有没有关于"阴影方法的特别之处&#34 ;;它们只是A类值的方法,恰好位于结构体内。
您只需使用reflecion API模仿您的b.A.Test()
即可。糟糕的是,反射并没有表现出普通Go所做的那种糖,所以你需要模仿的是(&((*b).A)).Test()
。
val.Elem(). // Go to *B
FieldByName("A"). // Find field named A
Addr(). // Take its address, since Test has a method receiver of type *A
MethodByName("Test"). // Find its method Test
Call([]reflect.Value{})
更新的代码:
http://play.golang.org/p/67xc66ULFz
(顺便说一句,调用方法接收器" self"在Go中不是惯用的。)