如何在golang中扩展一个没有函数体的函数。

huangapple go评论80阅读模式
英文:

How to extend a function without body in golang

问题

我想使用ippy04/messengerbot库来构建一个用于Facebook Messenger的机器人。

该库在接收新消息时使用了一个我无法理解的结构。在相关的库源文件中定义了以下函数类型(但没有具体实现):

type MessageReceivedHandler func(*MessengerBot, Event, MessageOpts, ReceivedMessage)

然后将该类型附加到实际的机器人上:

type MessengerBot struct {
    MessageReceived  MessageReceivedHandler
}

在代码的后面部分,它会这样调用

if bot.MessageReceived != nil {
    go bot.MessageReceived(bot, entry.Event, message.MessageOpts, *message.Message)
}

现在看起来,我需要在自己的包中为MessageReceivedHandler扩展一个具体的实现。我尝试了一些方法。

根据另一个SO线程,我做了这个:

import "github.com/ippy04/messengerbot"
type myMRH messengerbot.MessageReceivedHandler
func (mr myMRH) HRM() {
    log.Println("works!")
}

...但是那段代码从未被调用。

我还尝试了这样扩展bot.MessageReceived(我正在使用GinGonic):

router.POST("/webhook", func(c *gin.Context) {
    bot := messengerbot.NewMessengerBot(os.Getenv("FB_PAGE_ACCESS_TOKEN"), os.Getenv("FB_MESSENGER_VERIFY_TOKEN"))
    bot.Debug = true
    bot.MessageReceived = func(*MessengerBot, Event, MessageOpts, ReceivedMessage) {
        log.Println("works!")
    }
    bot.Handler(c.Writer, c.Request)
})

但是我不知道从哪里获取必要的函数变量,因为它们没有被库暴露出来。

有关如何实现MessageReceivedHandler的任何想法吗?


根据@mykola的答案,这是解决我的问题的完整解决方案:

router.POST("/webhook", func(c *gin.Context) {
    bot := messengerbot.NewMessengerBot(os.Getenv("FB_PAGE_ACCESS_TOKEN"), os.Getenv("FB_MESSENGER_VERIFY_TOKEN"))
    bot.Debug = true
    bot.MessageReceived = func(bot *messengerbot.MessengerBot, evt messengerbot.Event, opts messengerbot.MessageOpts, msg messengerbot.ReceivedMessage) {
        log.Println(msg.Message.Text)
    }
    bot.Handler(c.Writer, c.Request)
})
英文:

I want to user the ippy04/messengerbot library to build a bot for the facebook messenger.

For receiving a new message the library uses a construct I can´t wrap my head around. The following function type is defined (but without body) in the relevant library source file:

type MessageReceivedHandler func(*MessengerBot, Event, MessageOpts, ReceivedMessage)

This type then gets attached to the actual bot:

type MessengerBot struct {
    MessageReceived  MessageReceivedHandler
}

Later in the code it gets called like this:

if bot.MessageReceived != nil {
    go bot.MessageReceived(bot, entry.Event, message.MessageOpts, *message.Message)
}

Now it seems I need to extend MessageReceivedHandler with an actual body implementation in my own package. I tried a few thing.

Following another SO thread I did this:

import "github.com/ippy04/messengerbot"
type myMRH messengerbot.MessageReceivedHandler
func (mr myMRH) HRM() {
	log.Println("works!")
}

... but that code never gets called.

Also I tried to extend bot.MessageReceived like this (I´m using GinGonic)

router.POST("/webhook", func(c *gin.Context) {
	bot := messengerbot.NewMessengerBot(os.Getenv("FB_PAGE_ACCESS_TOKEN"), os.Getenv("FB_MESSENGER_VERIFY_TOKEN"))
	bot.Debug = true
	bot.MessageReceived = func(*MessengerBot, Event, MessageOpts, ReceivedMessage) {
		log.Println("works!")
	}
	bot.Handler(c.Writer, c.Request)
})

but then I have no idea where to get the necessary function variables from since they ar enot exposed by the library.

Any idea on how to implement that MessageReceivedHandler?


Based on the answer from @mykola here is the complete solution to my problem:

router.POST("/webhook", func(c *gin.Context) {
	bot := messengerbot.NewMessengerBot(os.Getenv("FB_PAGE_ACCESS_TOKEN"), os.Getenv("FB_MESSENGER_VERIFY_TOKEN"))
	bot.Debug = true
	bot.MessageReceived = func(bot *messengerbot.MessengerBot, evt messengerbot.Event, opts messengerbot.MessageOpts, msg messengerbot.ReceivedMessage) {
		log.Println(msg.Message.Text)
	}
	bot.Handler(c.Writer, c.Request)
})

答案1

得分: 2

某人在某处声明了一个派生自messengerbot.MessageReceivedHandler的新类型,并不应该对机器人库本身产生任何影响。

你需要做的是在构造点设置机器人的处理程序,可以通过自己实例化它来完成,或者稍后通过以下方式进行设置:

bot.MessageReceived = func(bot *MessengerBot, evt Event, opts MessageOpts, msg ReceivedMessage) {
  log.Println("works!", msg)
}

附注:如果你还没有查看过 Go 语言之旅,你可能需要查看一下,因为你似乎对使用 Go 的基本概念有些不了解。

英文:

The fact that someone somewhere has declared a new type derived from messengerbot.MessageReceivedHandler doesn't and shouldn't have any effect on the bot library itself.

What you need is to set the handler of the bot either at the construction point, by instantiating it yourself, or later by doing

bot.MessageReceived = func(bot *MessengerBot, evt Event, opts MessageOpts, msg ReceivedMessage) {
  log.Println("works!", msg)
}

P.S. You might want to check the tour of go if you haven't yet, as you seem to miss some basic concepts of working with go.

huangapple
  • 本文由 发表于 2017年1月29日 18:02:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/41919644.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定