Динамически вызывать метод в интерфейсе {} независимо от типа получателя

Я работаю над системой шаблонов, написанной на 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{} по определению является ссылочным объектом.

Ответы на вопрос(3)

Ваш ответ на вопрос