Llamar dinámicamente al método en la interfaz {} independientemente del tipo de receptor

Estoy trabajando en un sistema de plantillas escrito en Go, lo que significa que requiere un uso liberal de lareflect paquete. En esta circunstancia específica necesito poder llamar dinámicamente un método en uninterface{}. La rareza es que mi lógica de reflexión funciona bien siempre que mis datos sean de un tipo conocido, pero no si los datos son de tipointerface{}.

El siguiente ejemplo puede ver que la lógica enmain() yPass() es idéntico. La única diferencia es si los datos son un tipo conocido o un tipo conocido dentro de uninterface{}

Ir a jugar: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")
    }
}

Al ejecutar este código obtenemos el siguiente resultado

Pass() fail
startfinish

Lo que significa que mi metodología para llamar dinámicamente a un método funciona bien, excepto en un escenario cuando mi objeto se encuentra actualmente en uninterface{}.

Si por el contrario no uso un receptor de puntero y pasei entonces funciona como se espera.

Ir a jugar:http://play.golang.org/p/myM0UXVYzX

Esto me lleva a creer que mi problema es que no puedo acceder a la dirección de i (&i) cuando es uninterface{}. He rastreado el paquete reflectante y he probado cosas comoreflect.Value.Addr() yreflect.PtrTo() Pero tampoco pude llegar a trabajar como yo necesitaba. Mi corazonada es que tiene algo que ver con el hecho de que unainterface{} Es por definición un objeto de referencia.

Respuestas a la pregunta(3)

Su respuesta a la pregunta