使用其他包中未导出的方法实现接口
在 Go 中,接口充当契约,定义了一组必须由任何遵循它的类型。通常,导出接口的方法以允许从其他包进行访问。但是,在某些情况下,您可能需要对使用程序隐藏特定的实现。
考虑以下示例,其中我们定义了用于会计系统访问的接口:
package accounting import "errors" type IAdapter interface { GetInvoice() error }
隐藏具体实现,我们不导出接口方法,并在基础包中引入包装函数,这些函数通过适配器:
var adapter IAdapter func SetAdapter(a IAdapter) { adapter = a } func GetInvoice() error { if (adapter == nil) { return errors.New("No adapter set!") } return adapter.GetInvoice() }
虽然这种方法看起来很有前途,但在尝试在另一个包中实现接口时遇到了问题。编译器抱怨无法看到未导出的 GetInvoice 方法。
这个问题源于 Go 中接口的工作方式。接口仅由方法签名组成,不了解其实现。当类型实现接口时,它必须公开与接口具有相同签名的所有方法。
为了克服此限制,我们可以利用匿名结构体字段:
type Adapter struct { accounting.IAdapter }
这允许我们可以通过匿名嵌入的方式在另一个包中实现该接口,但我们无法为未导出的方法提供自定义实现。
更惯用的方法解决方案是公开未导出的适配器并在基础包中提供注册函数:
package accounting type IAdapter interface { GetInvoice() error } --- package accountingsystem type adapter struct {} func (a adapter) GetInvoice() error {return nil} func SetupAdapter() { accounting.SetAdapter(adapter{}) } --- package main func main() { accountingsystem.SetupAdapter() }
此方法可确保适配器保持隐藏状态,同时仍允许注册适当的实现。
以上是如何使用另一个 Go 包中未导出的方法实现接口?的详细内容。更多信息请关注PHP中文网其他相关文章!