私はGoで書かれたテンプレートシステムで作業しています。つまり、reflect
パッケージを自由に使用する必要があります。この特定の状況では、私はinterface{}
でメソッドを動的に呼び出すことができる必要があります。奇妙なのは、データが既知の型のデータであれば、私のリフレクションロジックは正常に動作しますが、データの型がinterface{}
ではないことです。受信者の種類に関係なく、インタフェース{}のメソッドを動的に呼び出す
次の例では、main()
とPass()
のロジックが同一であることがわかります。 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{}
内部の既知のタイプまたは既知のタイプであるかどうかでありますオブジェクトが現在interface{}
にある場合を除いて、メソッドを動的に呼び出すための私の方法論がうまく動作することを意味します。
代わりに私はポインタ受信機を使用せず、i
を渡すと、期待通りに動作します。
Goは再生:http://play.golang.org/p/myM0UXVYzX
をこれが私の問題は、それがinterface{}
あるとき、私は私(&i
)のアドレスにアクセスすることができないということであると信じて私をリードしています。私は反映パッケージを精査して、reflect.Value.Addr()
とreflect.PtrTo()
のようなものをテストしましたが、私が必要な方法で作業することができませんでした。私の感想は、それはinterface{}
が参照オブジェクトであるという事実と関係があるということです。
ありがとうございます。私の質問は異なっていましたが、あなたの答えは、構造体に 'IsValid()'メソッドがあるかどうか判断するのに役立ちました。 – Matt
私自身の質問に答えるときに私はこれを考え出しました(http://play.golang.org/p/v7lC0swB3s)(http://stackoverflow.com/questions/20167935/can-embedded-methods-access-parent -fields) – Brenden