通过反射获取阴影方法

时间:2014-03-13 09:17:25

标签: reflection go

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

在下面的代码中,我使用MethodByName来获取Test()类型的方法B,但我想从{{1}获取带阴影的方法Test()同样,我可以同时打电话给他们。

b.A

此处提供的代码:http://play.golang.org/p/6YPLy2dmMb

2 个答案:

答案 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指针通常是透明的,但遗憾的是它并不适用于反射,所以你必须自己做所有明确的寻址/解除引用,但如果你理解了指针,它就非常简单。

修改:Playground link to the code above

答案 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中不是惯用的。)