我有一个定义为
的函数签名类型type MessageListener func(msg *Message) bool
在结构中,我定义了以下函数,它基本上使用上面类型定义的函数签名注册一个Listener
func (wm *WM) AddListener(listener *MessageListener) error {
...
}
我的服务结构
type Service struct {
...
}
func (service *Service) receiveMessage(msg *Message) bool {
...
}
当我这样做时,为什么会出现不兼容的类型错误
wm.AddListener(&service.receiveMessage)
service.receiveMessage
不具有MessageListener
类型吗?
答案 0 :(得分:2)
因为函数是引用,所以您不需要使用任何指针或尝试获取函数的地址 只需声明
func (wm *WM) AddListener(listener MessageListener) error {
...
}
// and get rid of taken address of function
wm.AddListener(service.receiveMessage)
答案 1 :(得分:1)
MessageListener
已经是函数指针,因此您只需将AddListener
定义为
func (wm *WM) AddListener(listener MessageListener) error {
//...
}
然后可以通过调用wm.AddListener(service.receiveMessage)
来注册侦听器。
来自Address operator的规格:
对于类型为T的操作数x,地址操作& x生成类型为* T到x的指针。操作数必须是可寻址的,即,变量,指针间接或切片索引操作;或可寻址结构操作数的字段选择器;或者可寻址数组的数组索引操作。作为可寻址性要求的例外,x也可以是(可能带括号的)复合文字。如果x的评估会导致运行时恐慌,那么& x的评估也会发生。
所以你不能获取函数/方法的地址。但是,您可以获取存储函数/方法的变量的地址。将侦听器声明为
是有效的func (wm *WM) AddListener(listener *MessageListener) error {
//...
}
但是在注册监听器时,请执行以下操作:
var fn MessageListener = service.receiveMessage
wm.AddListener(&fn)
并且在调用侦听器时:
msg := Message{//...}
(*wm.listener)(&msg)
添加了不必要的代码,用于将函数变量转换为指针,然后转换回函数变量。