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

Dar*_*ren 9 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()
}


__________________________________________________

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)
}
Run Code Online (Sandbox Code Playgroud)

这个问题是编译器抱怨,因为无法看到getInvoice()by 的实现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
Run Code Online (Sandbox Code Playgroud)

有没有办法在另一个包中实现带有未导出方法的接口?或者我是否以非惯用的方式思考这个问题?

Sim*_*Fox 13

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

type Adapter struct {
    accounting.IAdapter
}
Run Code Online (Sandbox Code Playgroud)

我无法使用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()
}
Run Code Online (Sandbox Code Playgroud)