我已经为会计系统访问编写了一个接口。我想从我的程序中隐藏接口的具体实现,因为我只会有一个" active"会计系统。所以我计划将接口的方法取消导出(隐藏),然后导出基本包的原生函数,从本地适配器调用相同的函数。
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()
无法看到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
有没有办法在另一个包中使用未导出的方法实现接口?或者我是否以非惯用的方式思考这个问题?
答案 0 :(得分:13)
您可以使用匿名结构字段实现具有未导出方法的接口,但是您无法提供自己的未导出方法实现。例如,此版本的Adapter满足accounting.IAdapter接口。
type Adapter struct {
accounting.IAdapter
}
我无法使用Adapter来提供我自己的IAdapter.getInvoice()方法实现。
这个技巧对你没有帮助。
如果您不希望其他软件包直接使用accountingsystem.Adapter,则将类型取消导出并添加一个函数,以便使用记帐包注册适配器。
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()
}