dongxibo2095 2014-10-03 14:49
浏览 7
已采纳

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

I have written an interface for accounting system access. I would like to hide specific implementations of the interface from my program as I will only ever have one "active" accounting system. So I planned on making the methods of the interface unexported (hidden), and then having exported functions native to the base package that call a the same function from a local adapter.

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

The problem with this is that the compiler complains, due to not being able to see the implementation of 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

Is there any way of being able to implement an interface with unexported methods in another package? Or am I thinking about this problem in a non-idiomatic way?

  • 写回答

1条回答 默认 最新

  • douze2890241475 2014-10-03 15:06
    关注

    You can implement an interface with unexported methods using anonymous struct fields, but you cannot provide your own implementation of the unexported methods. For example, this version of Adapter satisfies the accounting.IAdapter interface.

    type Adapter struct {
        accounting.IAdapter
    }
    

    There's nothing that I can do with Adapter to provide my own implementation of the IAdapter.getInvoice() method.

    This trick is not going to help you.

    If you don't want other packages to use accountingsystem.Adapter directly, then make the type unexported and add a function for registering the adapter with the accounting package.

    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()
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度