通过反射获得阴影方法



如何通过反射获得阴影方法?

在下面的代码中,我使用MethodByName来获取类型B上的方法Test(),但我也想从b.A中获得阴影方法Test(),所以我可以调用它们。

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()   // This one shadows b.A.Test()
    b.A.Test() // but its ok to call like this
    // via reflection
    val := reflect.ValueOf(b)
    val.MethodByName("Test").Call([]reflect.Value{})
}

代码可在此获取:http://play.golang.org/p/6YPLy2dmMb

如果您有一个嵌入式结构体和阴影,您总是可以获得字段,就好像它是一个与嵌入式结构体类型同名的成员变量一样,这在b.A.Test()行中显示。

我们该怎么做?使用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指针通常是透明的,但不幸的是,它不适用于反射,因此您必须自己执行所有显式寻址/解引用,但如果您了解指针,则非常简单。

编辑:Playground链接到上面的代码

当你将一个结构体嵌入到另一个结构体中,比如a嵌入到B中,你只是在结构体B中创建了一个名为a的类型为a的字段。作为语法上的方便,你可以直接在B上调用a上的方法,但在语义上没有关于"阴影方法"的特殊事情;它们只是碰巧在结构体内部的a型值的方法。

你只需要用反射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中不是习惯用法。)

相关内容

  • 没有找到相关文章

最新更新