有没有办法编写一个接口,可以接收任何函数,而不管它在go中的签名如何?

问题描述 投票:0回答:1

我有一个看起来有点像的函数

func (c *Context) RegisterHandler(f interface{}) error {
    // Do lots of checking to make sure a function was passed in
    // and it's arguments all implement a specific interface
}

func consumer(a ConcreteTypeA, b ConcreteTypeB) {}

func main() {
    ...
    c.RegisterHandler(consumer)
}

大致可以归结为

var a ConcreteTypeA
var b ConcreteTypeB
a.InitFromContext(c)
b.InitFromContext(c)
consumer(a, b)

有没有办法让

interface{}
更具体而不改变它的行为?如果不是,我对我的解决方案相当满意。我只是希望我可以减少运行时检查和编译时可能未被捕获的错误。

我当前的实现看起来与上面非常相似。我尝试过做类似的事情

func (c *Context) RegisterHandler(f func (...InitFromContexter)) error {
    // Do lots of checking to make sure a function was passed in
    // and it's arguments all implement a specific interface
}

但这会导致所有现有代码失败,因为它只会接收可变参数函数

go types reflection
1个回答
0
投票

你已经用你的

RegisterHandler(f interface{})
找到了路,真的没有其他的了。

事实是,如果您想支持多个签名,您还需要有代码来处理您支持的所有各种签名模式,以便最终可以实际进行调用。

正如您已经写的,这将是一个运行时检查的意大利面条球,实际上也是基于反射的检查和调用。如果在您的项目中可行的话,拥有类似

RegisterHandler(handler interface{ Do() }
的内容可能会更清晰、更容易理解(尤其是在以后),其中您的各种不同模式显示为特定于实现的结构字段。

© www.soinside.com 2019 - 2024. All rights reserved.