我有一个看起来有点像的函数
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
}
但这会导致所有现有代码失败,因为它只会接收可变参数函数
你已经用你的
RegisterHandler(f interface{})
找到了路,真的没有其他的了。
事实是,如果您想支持多个签名,您还需要有代码来处理您支持的所有各种签名模式,以便最终可以实际进行调用。
正如您已经写的,这将是一个运行时检查的意大利面条球,实际上也是基于反射的检查和调用。如果在您的项目中可行的话,拥有类似
RegisterHandler(handler interface{ Do() }
的内容可能会更清晰、更容易理解(尤其是在以后),其中您的各种不同模式显示为特定于实现的结构字段。