英文:
How to use an interface in a callback with Golang?
问题
我正在尝试使用Go语言的Faye客户端,但是当我尝试为客户端创建一个接口时,由于回调函数中的类型问题,似乎出现了错误。
在这一点上,它会出现以下错误:
# command-line-arguments
main/fayetest.go:27: cannot use wray.NewFayeClient("http://localhost/faye") (type *wray.FayeClient) as type Subscriber in argument to subscribeMe:
*wray.FayeClient does not implement Subscriber (wrong type for Subscribe method)
have Subscribe(string, bool, func(wray.Message)) (wray.SubscriptionPromise, error)
want Subscribe(string, bool, func(Message)) (Promise, error)
看起来应该是可以工作的,因为客户端确实满足接口的要求。
作为一个旁白,我是Faye客户端的作者,有什么我可以做的来使其适应接口吗?除了放弃回调函数之外?
英文:
I am trying to use a Faye client for Go but when I try to make an interface for the client it seems to fail due to to the type in the callback:
package main
import (
"fmt"
"github.com/autogrowsystems/wray"
)
type Message interface {
Data() map[string]interface{}
}
type Promise interface {
Successful() bool
}
type Subscriber interface {
Subscribe(string, bool, func(Message)) (Promise, error)
}
func subscribeMe(subber Subscriber) {
subber.Subscribe("/my/chan", false, func(msg Message) {
fmt.Printf("got data: %+v", msg.Data())
})
}
func main() {
subscribeMe(wray.NewFayeClient("http://localhost/faye"))
fmt.Println("all good!")
}
At that point it fails with the following error:
# command-line-arguments
main/fayetest.go:27: cannot use wray.NewFayeClient("http://localhost/faye") (type *wray.FayeClient) as type Subscriber in argument to subscribeMe:
*wray.FayeClient does not implement Subscriber (wrong type for Subscribe method)
have Subscribe(string, bool, func(wray.Message)) (wray.SubscriptionPromise, error)
want Subscribe(string, bool, func(Message)) (Promise, error)
It seems as though it should work as the client does satisfy the interface:
// wray.go - wray.FayeClient
func (self *FayeClient) Subscribe(channel string, force bool, callback func(Message)) (promise SubscriptionPromise, err error) {
}
// response.go - wray.Message
func (self Message) Data() map[string]interface{} {
}
// wray.go - wray.SubscriptionPromise
func (self SubscriptionPromise) Successful() bool {
}
It should work right? Or does the callback mess up the satisfaction of the interface?
Edit: as an aside, I am the author of that fork of the Faye Client, is there anything I can do to make it conducive to interfaces? Apart from ditching callbacks?
答案1
得分: 4
FayeClient.Subscribe
实现了以下函数:
Subscribe(string, bool, func(wray.Message)) (wray.SubscriptionPromise, error)
而你的 Subscriber
接口要求的函数是:
Subscribe(string, bool, func(Message)) (Promise, error)
请注意回调函数的参数不同 (Message
!= wray.Message
,Promise
!= wray.SubscriptionPromise
),这就是为什么你的代码无法编译的原因。
你不需要重新声明 Message
和 Promise
接口,只需使用库中的接口即可。
英文:
FayeClient.Subscribe
implements:
Subscribe(string, bool, func(wray.Message)) (wray.SubscriptionPromise, error)
and your interface Subscriber requires the function:
Subscribe(string, bool, func(Message)) (Promise, error)
Notice the different parameters of the callback function (Message
!= wray.Message
, Promise
!= wray.SubscriptionPromise
), and that's why your code won't compile.
You don't need to declare the interfaces Message
and Promise
again, just use the ones from the library.
答案2
得分: 0
尽管你声称wray.FayeClient
实现了你的Subscriber
接口,但它的Subscribe
方法与接口中定义的方法具有不同的签名。
Subscribe(string, bool, func(wray.Message)) (wray.SubscriptionPromise, error)
和Subscribe(string, bool, func(Message)) (Promise, error)
并不是同一回事。wray.Message
可能实现了Message
接口,但它仍然是不同的类型。wray.SubscriptionPromise
和Promise
也是如此。
如果你想使你的库更适合接口,你需要修改库本身,使其接受接口参数并返回接口,而不是具体类型。
英文:
Despite what you claim, wray.FayeClient
doesn't implement your Subscriber
interface, because it's Subscribe
method has a different signature from the one defined in your interface.
Subscribe(string, bool, func(wray.Message)) (wray.SubscriptionPromise, error)
simply is not the same thing as Subscribe(string, bool, func(Message)) (Promise, error)
. wray.Message
may implement Message
, but it's still a different type. Same goes for wray.SubscriptionPromise
and Promise
.
If you want to make your library more conducive to interfaces, you need to change the library itself to accept interface arguments and return interfaces instead of concrete types.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论