2017-08-01 75 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) 

這增加了不必要的代碼用於將函數變量轉換爲指針,然後轉換回函數變量。