2015-06-30 20 views
-2

我希望能夠將函數名稱傳遞給gin.Engine路由處理程序。我有以下代碼;從地圖[字符串]接口{}通過給定鍵調用函數

// status service 
type StatusService struct { 
    App *gin.Engine 
} 

func (s *StatusService) Ping(ctx *gin.Context) { 
    ctx.JSON(200, gin.H{ 
     "message": "pong", 
    }) 
} 

app := gin.Default() 
// define services 
statusService := &services.StatusService{ 
    App: app, 
} 
ss := make(map[string]interface{}) 
ss["auth"] = statusService 

app.GET("/ping", ss["auth"].Ping) 

編譯器給出以下錯誤;

./app.go:60: ss["auth"].Ping undefined (type interface {} has no field or method Ping) 

有關如何解決這個問題的任何想法?

回答

2

interface{}適用於任何類型,問題是您未能斷言哪種類型是事物。在這種情況下,您需要類似...... ss["auth"].(*StatusService).Ping(myCtxInstance)。這個答案有一個更徹底的例子,我會避免重複; Go map of functions

夫妻其他的事情;如果您的實際用例與您的示例一樣簡單,請停止正在執行的操作並將func(ctx *gin.Context)作爲第二個參數添加。另外,根據你想要使用的函數的性質(如果它們都具有相同的參數和返回類型),那麼你可能想爲代表使用第二個參數,map[string]func(argumentType)會更合適。

您目前所設計的設計將所有錯誤都推送到運行時,這顯然比您從上述任一選項中獲得的編譯時安全性要低。

+0

好吧,我不必定義一個映射結構。我可以初始化一個var並將它的函數傳遞給'app.GET()'。使用它更方便嗎? – aacanakin

+0

btw,'ss [「auth」]。(func(ctx * gin.Context))。Ping'不起作用 – aacanakin

+0

@aacanakin是的,有一件事我沒有注意到,那就是你有一個接收''Status *'類型爲'Ping',所以你實際上需要爲這個類型聲明assert。我會更新這個例子。 – evanmcdonnal