不能使用接口的实现作为要接口的func的参数

时间:2017-11-28 18:42:04

标签: go reflection interface

我收到以下错误:

./main.go:31: cannot use telegramService (type messaging.TelegramService) as type mypackage.MessagingService in argument to mypackage.RegisterMessagingService:
    messaging.TelegramService does not implement mypackage.MessagingService (wrong type for HandleIncomingMessage method)
        have HandleIncomingMessage(telegram.Message) error
        want HandleIncomingMessage(mypackage.IncomingMessage) error

我有一个描述Telegram或WhatsApp等消息服务的接口,以及一个描述来自其中一个服务的传入消息的接口:

// IncomingMessage is a message that comes in on a messaging service
type IncomingMessage interface {
    Send() error
}

// MessagingService is a service on which messages can be send (like Telegram or FB Messenger)
type MessagingService interface {
    Start()
    HandleIncomingMessage(IncomingMessage) error
    GetHTTPHandler() http.HandlerFunc
    GetCommands() []MessagingCommand
}

MessagingService的第一个实现是Telegram。问题是HandleIncomingMessage函数,它目前没有做任何事情,只是看起来像这样:

// HandleIncomingMessage will take an incoming message and repond to it
func (s TelegramService) HandleIncomingMessage(msg *telegram.Message) error {

    return nil
}

问题是这个函数接受telegram.Message,编译器说它不符合接口。问题是,telegram.MessageIncomingMessage实现

// Message is a Telegram message
type Message struct {
    // Added the line below at some point, but it didn't work without it either
    mypackage.IncomingMessage
    MessageID uint64 `json:"message_id"`
    FirstName string `json:"first_name"`
    Username  string `json:"username"`
    Date      uint64 `json:"date"`
    Text      string `json:"text"`
    Chat      Chat   `json:"chat"`
    From      User   `json:"from"`
}

// Send will take m and send it
func (m Message) Send() error {
    // Do stuff

    return nil
}

最初IncomingMessage是一个空接口,这是我第一次注意到这个问题的地方。我尝试添加我要添加的函数Send(),因为我想也许只是给它任何结构都行不通。但是,我仍然收到此错误。

我没有看到telegram.Message没有实现接口的原因,这很简单。

任何人都可以解释为什么这不起作用?

PS:我的包裹实际上并未被称为mypackage,为清晰起见而进行了更改

1 个答案:

答案 0 :(得分:0)

HandleIncomingMessage必须采用IncomingMessage参数,因为这是定义接口的方式。您无法定义HandleIncomingMessage的实现,该实现将其他类型作为参数,即使该类型实现IncomingMessage。您可以定义函数以使用IncomingMessage并使用类型断言将其转换为*telegram.Message

func (s TelegramService) HandleIncomingMessage(im IncomingMessage) error {
    msg := im.(*telegram.Message)
    return nil
}

我假设您确实想要使用指向telegram.Message的指针。如果是这样,您需要更改Send方法的定义以获取指针接收器。