我已经编写了用于会计系统访问的界面。我想从我的程序中隐藏接口的特定实现,因为我将永远只有一个“活动的”记帐系统。因此,我计划将接口的方法设置为不导出(隐藏),然后导出基本包中固有的导出函数,这些函数从本地适配器调用相同的函数。
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() } __________________________________________________ package accountingsystem type Adapter struct {} func (a Adapter) getInvoice() error {return nil} __________________________________________________ package main import ( "accounting" "accountingsystem" ) function main() { adapter := accountingsystem.Adapter{} accounting.SetAdapter(adapter) }
问题在于,由于无法看到getInvoice()by 的实现,编译器会抱怨accountingsystem.Adapter:
getInvoice()
accountingsystem.Adapter
./main.go:2: cannot use adapter (type accountingsystem.Adapter) as type accounting.IAdapter in argument to accounting.SetAdapter: accountingsystem.Adapter does not implement accounting.IAdapter (missing accounting.getInvoice method) have accountingsystem.getInvoice() error want accounting.getInvoice() error
有什么方法可以用另一个包中的未导出方法实现接口?还是我以一种非惯常的方式思考这个问题?
您可以使用匿名结构字段使用未导出的方法来实现接口,但是不能提供自己的未导出方法的实现。例如,此版本的适配器满足Accounting.IAdapter接口。
type Adapter struct { accounting.IAdapter }
我无法使用Adapter来提供我自己的IAdapter.getInvoice()方法的实现。
这个技巧不会帮助您。
如果您不希望其他软件包直接使用accountingsystem.Adapter,则将其类型设置为unexported,并添加一个用于将适配器注册到计费软件包的功能。
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() }