Невозможно использовать неявные Go интерфейсы через плагины - PullRequest
0 голосов
/ 14 февраля 2020

У меня есть Go файл с кодом ниже. Я скомпилировал это в файл плагина .so.

// +build engine

package main

func DoStuff(t interface { Do() }) {
    t.Do()
}

Затем main. go, который его вызывает:

package main

import (
    "fmt"
    "plugin"
    "reflect"
)

func main() {
    plug, _ := plugin.Open("test.so")
    testFunc, _ := plug.Lookup("DoStuff")

    impl := Implementation{}

    actualFunc, ok := testFunc.(func(d interface{ Do() }))
    if !ok {
        panic(reflect.TypeOf(testFunc))
    }

    actualFunc(impl)
}

Скомпилируйте и запустите с go build -buildmode=plugin -tags engine -o test.so ./ && go build . && ./test. Этот подход работает отлично, и я получаю ожидаемое "работающее" эхо.

Если я изменю его на;

// +build engine

package main

type StuffInterface interface {
    Do()
}

func DoStuff(t StuffInterface) {
    t.Do()
}

для плагина и вызов на;

package main

import (
    "fmt"
    "plugin"
    "reflect"
)

func main() {
    plug, _ := plugin.Open("test.so")
    testFunc, _ := plug.Lookup("DoStuff")

    impl := Implementation{}

    actualFunc, ok := testFunc.(func(d LocalInterface))
    if !ok {
        panic(reflect.TypeOf(testFunc))
    }

    actualFunc(impl)
}

type LocalInterface interface {
    Do()
}

type Implementation struct { }

func (t Implementation) Do() {
    fmt.Println("works")
}

Или вот так;

package main

import (
    "fmt"
    "plugin"
    "reflect"
)

func main() {
    plug, _ := plugin.Open("test.so")
    testFunc, _ := plug.Lookup("DoStuff")

    impl := Implementation{}

    actualFunc, ok := testFunc.(func(d interface{ Do() }))
    if !ok {
        panic(reflect.TypeOf(testFunc))
    }

    actualFunc(impl)
}

type Implementation struct { }

func (t Implementation) Do() {
    fmt.Println("works")
}

он больше не работает, и я получаю пани c, которая печатает мне ожидаемый тип;

go build -buildmode=plugin -tags engine -o test.so ./ && go build . && ./test 
panic: func(main.StuffInterface)

goroutine 1 [running]:
main.main()
        /Users/dennis/test/main.go:17 +0x171

Может кто-нибудь объяснить, почему это не работает с другими 2 подходами? Go интерфейсы неявные, поэтому я понимаю, что это должно работать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...