我正在开发一个用 Go 编写的模板系统,这意味着它需要自由使用该reflect
包。在这种特定情况下,我需要能够动态调用interface{}
. 奇怪的是,只要我的数据是已知类型,我的反射逻辑就可以正常工作,但如果数据是 type 则不行interface{}
。
下面的例子你可以看到main()
和中的逻辑Pass()
是相同的。唯一的区别是数据是已知类型还是内部已知类型interface{}
去玩:http ://play.golang.org/p/FTP3wgc0sZ
package main
import (
"fmt"
"reflect"
)
type Test struct {
Start string
}
func (t *Test) Finish() string {
return t.Start + "finish"
}
func Pass(i interface{}) {
_, ok := reflect.TypeOf(&i).MethodByName("Finish")
if ok {
fmt.Println(reflect.ValueOf(&i).MethodByName("Finish").Call([]reflect.Value{})[0])
} else {
fmt.Println("Pass() fail")
}
}
func main() {
i := Test{Start: "start"}
Pass(i)
_, ok := reflect.TypeOf(&i).MethodByName("Finish")
if ok {
fmt.Println(reflect.ValueOf(&i).MethodByName("Finish").Call([]reflect.Value{})[0])
} else {
fmt.Println("main() fail")
}
}
执行此代码后,我们得到以下结果
Pass() fail
startfinish
这意味着我动态调用方法的方法可以正常工作,除非我的对象当前位于interface{}
.
相反,如果我不使用指针接收器并通过,i
那么它会按预期工作。
去玩:http ://play.golang.org/p/myM0UXVYzX
这让我相信我的问题是&i
当 i() 是一个interface{}
. 我已经搜索了反射包并测试了诸如reflect.Value.Addr()
和之类的东西,reflect.PtrTo()
但是我无法按照我需要的方式工作。我的预感是它与 aninterface{}
定义为引用对象这一事实有关。