2017-08-01 79 views
0

我有定义为函数签名类型

在一个结构的函数签名的类型时,我已经定义下面的函数基本上与由类型以上

定义函数签名注册一个监听器
func (wm *WM) AddListener(listener *MessageListener) error { 
... 
} 

我的服务结构

type Service struct { 
    ... 
} 

func (service *Service) receiveMessage(msg *Message) bool { 
    ... 
} 

为什么我收到一个INCOMP atible类型的错误,当我做

wm.AddListener(&service.receiveMessage) 

service.receiveMessage有型MessageListener

回答

2

因为该函数是一个引用,所以不需要使用任何指针或尝试获取该函数的地址。
只是声明

func (wm *WM) AddListener(listener MessageListener) error { 
... 
} 
// and get rid of taken address of function 
wm.AddListener(service.receiveMessage) 
+0

工作示例https://play.golang.org/p/HiUfeibQ39 –

1

MessageListener已经是一个函数指针所以你可以简单地定义为AddListener

func (wm *WM) AddListener(listener MessageListener) error { 
    //... 
} 

然后侦听器可以通过调用wm.AddListener(service.receiveMessage)注册。

Address operator规格:

对于类型T,写入动作&的操作数X X生成类型* T的至x的指针。操作数必须是可寻址的,即变量,指针间接或片段索引操作;或可寻址结构操作数的字段选择器;或可寻址阵列的数组索引操作。作为寻址能力要求的一个例外,x也可以是(可能加括号的)复合文字。如果x的评估会导致运行时恐慌,那么评估也会如此。

所以你不能接受函数/方法的地址。但是,您可以获取存储函数/方法的变量的地址。它是有效的申报听者

func (wm *WM) AddListener(listener *MessageListener) error { 
    //... 
} 

但随后注册监听时,执行以下操作:

var fn MessageListener = service.receiveMessage 
wm.AddListener(&fn) 

并调用侦听器时:

msg := Message{//...} 
(*wm.listener)(&msg) 

这增加了不必要的代码用于将函数变量转换为指针,然后转换回函数变量。