Спасибо за это подробное объяснение. Решение о возврате с помощью публичной функции выглядит намного красивее, чем глобальная переменная. Я буду использовать этот метод в будущем.
лкиваюсь с поведением Го, которое я не понимаю. Моя идея заключается в том, чтобы импортировать плагин, который реализует интерфейс из обоих пакетов. Если возвращается структура, она работает нормально, но чтобы быть уверенным, что она реализует интерфейс, я хочу вернуть интерфейс, который не работает.
Определение интерфейса:
package iface
type IPlugin interface{
SayHello(string)
SayGoodby(string)
WhatsYourName() string
}
Основная программа выглядит так:
package main
import (
"plugin"
"plugin_test/iface"
"errors"
"fmt"
)
//go:generate go build -buildmode=plugin -o ./pg/test.so ./pg/test.go
func main(){
path := "pg/test.so"
plug, err := plugin.Open(path)
if err != nil {
panic(err)
}
sym, err := plug.Lookup("Greeter")
if err != nil {
panic(err)
}
var pg iface.IPlugin
pg, ok := sym.(iface.IPlugin)
if !ok {
panic(errors.New("error binding plugin to interface"))
}
fmt.Printf("You're now connected to: %s \n", pg.WhatsYourName())
pg.SayHello("user")
pg.SayGoodby("user")
}
Плагин (хранится в pg / test.go)
package main
import (
"fmt"
"plugin_test/iface"
)
type testpl struct {}
func(pl testpl) SayHello(s string){
fmt.Printf("Plugin says hello to %s \n", s)
}
func(pl testpl) SayGoodby(s string){
fmt.Printf("Plugin says goodby to %s \n", s)
}
func(pl testpl) WhatsYourName() string{
return "my name is Test-Plugin"
}
/* This function works */
func getPlugin() testpl{
return testpl{}
}
/* This function doesn't work */
func getPlugin() iface.IPlugin{
return testpl{}
}
/* This function also doesn't work */
func getPlugin() interface{}{
return testpl{}
}
var Greeter = getPlugin()
Я пробовал каждыйgetPlugin
функционировать самостоятельно.
Функция, возвращающаяtestpl
печатает ожидаемый результат:
You're now connected to: my name is Test-Plugin
Plugin says hello to user
Plugin says goodby to user
Остальные функции заканчиваются наsym.(iface.IPlugin)
panic: error binding plugin to interface
goroutine 1 [running]:
main.main()
/home/../../../main.go:27 +0x343
exit status 2
Может кто-нибудь объяснить, почему это невозможно? Разве не было бы проще создать плагин, если бы он не позволил вам создать плагин в таком случае?