Dynamicznie wywołaj metodę na interfejsie {} niezależnie od typu odbiorcy

Pracuję nad systemem szablonów napisanym w Go, co oznacza, że ​​wymaga on swobodnego używaniareflect pakiet. W tej konkretnej sytuacji muszę być w stanie dynamicznie wywołać metodę nainterface{}. Dziwne jest to, że moja logika refleksji działa dobrze, dopóki moje dane są znanego typu, ale nie, jeśli dane są typuinterface{}.

W poniższym przykładzie widać, że logika wmain() iPass() jest identyczny. Jedyną różnicą jest to, czy dane są znanym typem, czy znanym typem wewnątrzinterface{}

CHodźmy grać: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")
    }
}

Po wykonaniu tego kodu otrzymujemy następujący wynik

Pass() fail
startfinish

Oznacza to, że moja metodologia dynamicznego wywoływania metody działa dobrze, z wyjątkiem scenariusza, w którym mój obiekt jest obecnie w trybieinterface{}.

Jeśli zamiast tego nie używam odbiornika wskaźnika i przekazujęi to działa zgodnie z oczekiwaniami.

CHodźmy grać:http://play.golang.org/p/myM0UXVYzX

To prowadzi mnie do przekonania, że ​​moim problemem jest to, że nie mogę uzyskać dostępu do adresu i (&i) kiedy to jestinterface{}. Przeszukałem pakiet i sprawdziłem takie rzeczy, jakreflect.Value.Addr() ireflect.PtrTo() ale nie mogłem ani pracować tak, jak potrzebowałem. Moje przeczucie jest takie, że ma to coś wspólnego z faktem, żeinterface{} jest z definicji obiektem odniesienia.

questionAnswers(3)

yourAnswerToTheQuestion