go - 将具有返回值的方法转换为具有接口(interface){}的方法

标签 go plugins

我有一个定义以下结构的插件:

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
}

但是,转换为 PluginInterfacePluginInterface2 失败。显然,如果我更改插件中 Do() 的方法定义以返回通用 interface{},则 PluginInterface2 转换会成功。

示例代码:https://play.golang.org/p/rB5zZVChSpc

最佳答案

你不能。更改 Plugin.Do() 的签名以返回插件外部定义类型的值(例如,在您的应用和插件使用的第三个包中定义),或返回例如接口(interface){}

查看相关问题:

如果不能更改插件,可以使用反射调用方法。调用 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/

相关文章:

Java:多个语言包不同版本,会发生什么?

javascript - CKEditor - 使某些文本只读

java - Gradle 和插件恶作剧,用于多模块构建

asynchronous - Go队列处理失败重试

go - 修复 Go 中的错误连接

api - 如何从 "test"包测试 Golang 中的主包?

plugins - jQuery 延迟加载是否有任何真正的性能提升?

go - dep init 上的“不在已知的 GOPATH/src 中”错误

使用提交哈希时 Go Modules "unknown revision"错误

go - 在 golang 中执行进程内动态插件的一种方法