2014-07-07 69 views
8

我是一個Go新手,今天我幾乎整天都在和這個問題鬥爭。接口{}到函數類型轉換

考慮到我有這些:

type HandlerType func() 
var object interface{} 
var typedObject HandlerType 

可以功能分配給typedObject變量是這樣的:

typedHandler = func() { 
    fmt.Println("in a handler!\n") 
} 

但我需要做的是通過該處理程序功能一個接口{}變量,然後將其轉換爲HandlerType,我可以稍後調用

我試過這個,但它引發錯誤:

typedHandler = object.(HandlerType) 

結果:

interface conversion: interface is func(), not main.HandlerType

基本上我需要無需額外的類型轉換註冊之前註冊到不同的簽名功能。因此,而不是這樣做:

registerHandler(HandlerTypeString(func() string { ... })) 
registerHandler(HandlerTypeVoid(func() { ... })) 

我要註冊的處理程序是這樣的:

registerHandler(func() string { ... }) 
registerHandler(func() { ... }) 

..我不想在處理程序調用的之後的時刻

涉及反射

這可能嗎?

編輯:我創建了一個遊樂場:http://play.golang.org/p/UlwqkHjt_P

所以據我所知是沒有辦法通過一些任意的功能接口{}然後以某種方式將其轉換爲HandlerType或其他一些預定義函數類型,所以我可以在不使用反射的情況下調用它?

EDIT2:我想出了這個解決方案:http://play.golang.org/p/4gUxsgmiPf

不應該有這種代碼在運行時的任何性能損失。但有人可以想出另一種實現這種功能的方式,而不需要interface {}

+1

顯示完整代碼中有一個例子。 'typedHandler = object。(HandlerType)**如果object(類型爲'interface {}')真的包含一個HandlerType對象,**將會工作。顯示在操場上播放的代碼。 – Volker

+1

另外一個:如果你是一個Go newcommer,你應該避免'interface {}'。 Finde以其他方式,作家適當的Go代碼。一個用於'interface'魔法的新手聞起來像是其他語言的代碼音譯。 – Volker

+0

我已經添加了一個操場,我想我已經明確了我想要完成什麼:) – user3668351

回答

4

你不能,這是一個不同的類型,你可以只使用object.(func())object.(func() string)

func main() { 
    type HandlerType func() 
    var object interface{} = func() { 
     fmt.Println("eureka!") 
    } 
    if f, ok := object.(func()); ok { 
     HandlerType(f)() 
    } 
} 
+0

謝謝!現在我已經有了如何實現我想要的東西。 http://play.golang.org/p/4gUxsgmiPf – user3668351

+0

其實對於這種特定的模式,你可能更喜歡使用像@Elwinar建議的界面。 – OneOfOne

6

有一些在你的問題小的誤解:

  1. 類型斷言不用於投射類型。它所做的只是檢查變量是否爲給定類型,並將變量作爲此基礎類型返回。此操作會在您的情況下返回錯誤,這是正常的,因爲func()不是HandlerFunc類型。

  2. 在接受interface{}的函數中,您不需要做任何事情來將變量作爲參數傳遞。每種類型都隱式實現空接口。

  3. func()不是HandlerType,即使HandlerTypetype HandlerType func()定義。該定義與此無關。

你想做什麼是不可能的。我不是反思專家,但我不認爲反思可以解決你的問題。

也就是說,你的註冊方法應該定義一個所有註冊對象應該實現的接口,並且使用這個接口作爲參數類型。舉例來看database/sqlRegister方法。