我正試圖在go中實現一組函數。上下文是一個事件服務器;我想阻止(或者至少警告)爲一個事件多次添加相同的處理程序。Go中唯一函數的集合
我已閱讀,地圖是地道的,因爲容易檢查會員的套使用方法:
if _, ok := set[item]; ok {
// don't add item
} else {
// do add item
}
我遇到了一些麻煩,使用這種模式的功能雖然。這是我第一次嘗試:
// this is not the actual signature
type EventResponse func(args interface{})
type EventResponseSet map[*EventResponse]struct{}
func (ers EventResponseSet) Add(r EventResponse) {
if _, ok := ers[&r]; ok {
// warn here
return
}
ers[&r] = struct{}{}
}
func (ers EventResponseSet) Remove(r EventResponse) {
// if key is not there, doesn't matter
delete(ers, &r)
}
很清楚爲什麼這不起作用:功能不引用類型在圍棋,雖然有些人會告訴你他們。 I have proof,儘管我們不需要它,因爲語言規範說除映射,切片和指針以外的所有東西都是按值傳遞的。
嘗試2:
func (ers EventResponseSet) Add(r *EventResponse) {
// ...
}
這有幾個問題:
任何顯示eventResponse必須聲明如下
fn := func(args interface{}){}
,因爲你不能滿足通常的方式聲明的函數。根本無法傳遞閉包。
使用包裝並不是一種選擇,因爲任何傳遞給包裝的函數都會從包裝中獲得一個新地址 - 沒有任何函數會被地址唯一標識,而所有這些仔細的計劃都是徒勞的。
難道我不接受定義函數作爲變量的解決方案嗎?是否有另一個(好的)解決方案?
要清楚,我接受有些情況下我無法捕捉(關閉),這很好。我設想的用例是定義一堆處理程序,並且相對安全,我不會無意中將兩個事件添加到同一事件兩次,如果這是有道理的。
如果鍵類型是'* EventResponse',那將無法捕獲兩次添加相同的函數,因爲你的鍵是一個指向任何變量指向函數的指針。你可能想看看'reflect'包 - 這可能會提供一種方法來做你想做的事。 –
函數不是[可比較的](https://golang.org/ref/spec#Comparison_operators)。您需要使用功能以外的其他功能作爲關鍵。 –
我知道這些功能沒有可比性。然而,[函數指針是](http://stackoverflow.com/a/9644797/1375316),這正是我想要做的。我的問題是函數不可尋址。你能提出一個很好的替代方案嗎?可以從函數本身獲得的東西,而不是由用戶/應用程序定義的東西? – threeve