将数据和函数与接口和结构相结合的组合

问题描述:

我在想,如果这是在Go中完成的事情,或者我正在考虑全部错误:编写type x interfacetype x struct,这样我的接口方法也可以访问特定的数据:将数据和函数与接口和结构相结合的组合

我希望C程序员做到这一点:

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

在那里,我有一个函数定义的接口,但也有一些数据我想通过这些功能,但是这是一个语法错误。

那么这是可行的通过其他方法或我只是在想问题的错误?

您错误地定义了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

TL; DR; Go没有直接翻译。

龙答:

围棋接口只有方法。

Go结构是只有数据(有接收方法的可能性)。

您可以参考,甚至嵌入接口结构中:

type Frobnicator interface { 
    Frobnicate() error 
} 

type Widget struct { 
    Frobnicator 
    WidgetName string 
} 

但是,这不是真的,你在说什么。

你的困境最好的答案是,我相信:退后一步。你专注于树木,你需要看看森林。 Go采用与C或C++和Java等经典OO语言不同的方法。

看看要解决的一般问题,并在Go中找到解决方案。这可能是一个痛苦的过程(我可以从经验中说出),但它是真正了解新思维方式的唯一途径。

只是为了记录在案,你可以添加额外的方法到现有的类型,通过引入另一(间接)类型:

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 
}