我有一个定义以下结构的插件:
type foo struct {
counter int64
}
type Plugin struct {}
func (p *Plugin) Do() *foo {
// Do something
return &foo{123}
}
在我的主应用程序中,我需要将插件转换为接口(interface)以便能够使用 Do()
。目前我不关心返回值(指向 foo
结构的指针),但拥有它会很好。
问题,如果我无法访问 foo
结构,我该如何转换和定义一个有效的接口(interface)?我尝试了以下选项:
type MyFoo struct {
counter int64
}
type PluginInterface interface {
Do() *MyFoo
}
type PluginInterface2 interface {
Do() interface{}
}
func main() {
plugin := Plugin{} // this would be code that loads bar as an interface {} from the plugin
do(&plugin)
}
func do(plugin interface{}) {
_, ok := plugin.(PluginInterface)
fmt.Println("OK with own Struct?", ok) // false
_, ok2 := plugin.(PluginInterface2)
fmt.Println("OK with generic interface?", ok2) // false
}
但是,转换为 PluginInterface
和 PluginInterface2
失败。显然,如果我更改插件中 Do()
的方法定义以返回通用 interface{}
,则 PluginInterface2
转换会成功。
最佳答案
你不能。更改 Plugin.Do()
的签名以返回插件外部定义类型的值(例如,在您的应用和插件使用的第三个包中定义),或返回例如接口(interface){}
。
查看相关问题:
- go 1.8 plugin use custom interface
- Is it possible to share a custom data type between a go plugin and an application?
- Can golang plugins be used for factory functions?
如果不能更改插件,可以使用反射调用方法。调用 Time.Hour()
的示例方法:
var x interface{} = time.Date(2019, 1, 1, 14, 0, 0, 0, time.UTC)
v := reflect.ValueOf(x)
hour := v.MethodByName("Hour")
results := hour.Call(nil)
fmt.Println(results[0])
它输出(在 Go Playground 上尝试):
14
关于go - 将具有返回值的方法转换为具有接口(interface){}的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57524484/