2017-04-13 86 views
1

我在想,如果這是在Go中完成的事情,或者我正在考慮全部錯誤:編寫type x interfacetype x struct,這樣我的接口方法也可以訪問特定的數據:將數據和函數與接口和結構相結合的組合

我希望C程序員做到這一點:

type PluginHandler interface { 
    onLoad() 
    pm *PluginManager 
} 
func (ph PluginHandler) onLoad() { 
    pm.DoSomething() 
} 

在那裏,我有一個函數定義的接口,但也有一些數據我想通過這些功能,但是這是一個語法錯誤。

那麼這是可行的通過其他方法或我只是在想問題的錯誤?

回答

2

您錯誤地定義了onLoad。您無法直接在接口類型上定義函數。

一旦你有一個接口,你需要另一個類型來實現在接口中指定的方法。例如,如果另一種類型實現onLoad方法,則它們自動(隱式)實現接口PluginHandler

你需要做的另一件事是改變接口函數類型接受所需的數據:

type PluginHandler interface { 
    onLoad(*PluginManager) 
} 

struct SomeType { 
    // ... 
} 

func (s SomeType) onLoad(pm *PluginManager) { // SomeType now implements 
    pm.DoSomething()       // PluginHandler interface. 
} 

這樣,你無論PluginManager通過PluginHandler需要注入。

此外,您可以根據需要使用SomeType作爲PluginHandler類型。

func someFuntion(ph PluginHandler) { 
    // ... 
    ph.onLoad(pm) 
    // ... 
} 

可與SomeType類型的輸入參數來調用:

s := SomeType{} 
someFunction(s) 
+0

謝謝!太棒了。我現在有一個適用於我的應用程序的插件系統:) – Southclaws

0

TL; DR; Go沒有直接翻譯。

龍答:

圍棋接口只有方法。

Go結構是只有數據(有接收方法的可能性)。

您可以參考,甚至嵌入接口結構中:

type Frobnicator interface { 
    Frobnicate() error 
} 

type Widget struct { 
    Frobnicator 
    WidgetName string 
} 

但是,這不是真的,你在說什麼。

你的困境最好的答案是,我相信:退後一步。你專注於樹木,你需要看看森林。 Go採用與C或C++和Java等經典OO語言不同的方法。

看看要解決的一般問題,並在Go中找到解決方案。這可能是一個痛苦的過程(我可以從經驗中說出),但它是真正瞭解新思維方式的唯一途徑。

0

只是爲了記錄在案,你可以添加額外的方法到現有的類型,通過引入另一(間接)類型:

type HandlerManager PluginManager 

func (x *HandlerManager) onLoad() { 
    ((*PluginManager)(x)).DoSomething() 
} 

如果你需要去一個更通用的解決方案的組合適配器&策略模式可以這樣做:

type PluginHandlerAdapter struct{ _onLoad func() } 

func (x *PluginHandlerAdapter) onLoad() { 
    x._onLoad() 
} 

一樣使用(忽略公共/私有訪問):

type PluginManager struct { 
    PluginHandlerAdapter 
} 

func NewPluginManager() *PluginManager { 
    res := new(PluginManager) 
    res._onLoad = res.DoSomething 
    return res 
}