私は Go で書かれたテンプレート システムに取り組んでいます。つまり、reflect
パッケージを自由に使用する必要があります。この特定の状況では、でメソッドを動的に呼び出すことができる必要がありますinterface{}
。奇妙なことに、データが既知の型である限り、私のリフレクション ロジックは正常に機能しますが、データが型である場合は機能しません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 パッケージを精査し、 and などをテストしましたreflect.Value.Addr()
がreflect.PtrTo()
、どちらも必要な方法で動作させることができませんでした。interface{}
私の推測では、 anが定義上参照オブジェクトであるという事実と関係があると思います。