Reputation: 83
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?
Upvotes: 1
Views: 2995
Reputation: 16534
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.
Upvotes: 4
Reputation: 4281
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.
Upvotes: 0