是否可以在另一个包中实现具有未导出方法的接口



我已经编写了一个会计系统访问接口。我想从我的程序中隐藏接口的具体实现,因为我只有一个"活动"会计系统。因此,我计划使接口的方法不被导出(隐藏),然后导出基本包的本机函数,这些函数从本地适配器调用相同的函数。

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)
}

这个问题是编译器抱怨,因为无法看到accountingsystem.Adapter:对getInvoice()的实现

./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

有没有任何方法可以在另一个包中用未导出的方法实现接口?还是我用一种不习惯的方式思考这个问题?

您可以使用匿名结构字段实现具有未导出方法的接口,但不能提供自己的未导出方法实现。例如,此版本的Adapter满足accounting.IAdapter接口。

type Adapter struct {
    accounting.IAdapter
}

我无法使用Adapter来提供我自己的IAdapter.getInvoice()方法实现。

这个把戏对你没有帮助。

如果您不希望其他程序包直接使用accountingsystem.Adapter,请使类型未导出,并添加一个用于向accounting程序包注册适配器的函数。

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()
}