首页 文章

使用接口定义的回调参数,使用实现调用

提问于
浏览
2

我正在做的事情:

我有一个库包,它定义了几种类型,都实现了给定的接口 . 在整个代码中,涉及回调,而不是在我为其定义类型的任何地方编写回调类型 .

type Foo interface {
    Bar()
}

type MyCallback func(f Foo)

type CoolFoo int

type BadFoo int

func (cf *CoolFoo) Bar(cb MyCallback) {
}

func (bf *BadFoo) Bar(cb MyCallback) {
}

然后从使用该库的客户端代码开始,我想使用回调调用 . 如果我通过使用接口类型调用它,它可以工作:

cf := &CoolFoo{}

cf.Bar(func(f packageName.Foo) {
})

但我宁愿在我的IDE中有更多的自我记录代码和正确的类型提示,所以我尝试使用implementsor类型调用它,例如:

cf := &CoolFoo{}

cf.Bar(func(f packageName.CoolFoo) {
})

哪个编译失败,错误:

不能在cf.Bar的参数中使用func文字(类型为func(packageName.CoolFoo))作为类型packageName.MyCallback

这是不可能的,还是我犯了一些假的错误?我在开发方面不是很有经验,我试过环顾四周,但在这里找不到解决方案 .

我发现它是将它作为Foo或接口{}传递然后在回调中转换为我想要的,但我想避免它,因为它感觉凌乱

谢谢你的帮助

1 回答

  • 3

    函数签名是 func(f Foo) ,因此这正是必须传递的内容 . 原因很简单:如果您的方法需要该签名的回调函数,它可以传入任何实现Foo的类型 . 如果你传入一个只接受 CoolFoo 的函数,调用者仍然可以传入 BadFoo ,因为你传递给它的类型,它将会失败,因为你需要代码支持.1490561_t .

    如果你的回调只传递 CoolFoo ,那么这可能是你在签名中使用的类型 . 如果 CoolFooBadFoo 每个只将它们各自的类型传递给它们的回调,那么你可能需要两个不同的回调签名 . 如果它们真的可以互换,那么你描述的情况(特别是 CoolFoo 的函数)对你的设计来说不是问题 .

相关问题