Динамически вызывать метод в интерфейсе {} независимо от типа получателя
Я работаю над системой шаблонов, написанной на Go, что означает, что она требует свободного использованияreflect
пакет. В этом конкретном случае мне нужно иметь возможность динамически вызывать метод наinterface{}
, Странность в том, что моя логика отражения работает нормально, пока мои данные относятся к известному типу, но не если данные относятся к типу.interface{}
В следующем примере вы можете увидеть, что логика вmain()
а такжеPass()
идентичен Единственная разница заключается в том, являются ли данные известным типом или известным типом внутриinterface{}
Go Play: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
тогда это работает как ожидалось.
Go Play:http://play.golang.org/p/myM0UXVYzX
Это заставляет меня поверить, что моя проблема в том, что я не могу получить доступ к адресу i (&i
) когда этоinterface{}
, Я'мы изучили пакет отражения и проверили такие вещи, какreflect.Value.Addr()
а такжеreflect.PtrTo()
но я не мог заставить работать так, как мне было нужно. Я догадываюсь, что это как-то связано с тем, чтоinterface{}
по определению является ссылочным объектом.