Is it possible to implement an interface with non-laid out methods in another package?

I wrote an interface to access the accounting system. I would like to hide specific implementations of the interface from my program, since I will have only one "active" accounting system. Therefore, I planned that the methods of the interface should not be exported (hidden), and then the functions would be exported that are native to the base package, which call the same function from the 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 is that the compiler complains about the inability to see the implementation of getInvoice() on 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 a way to implement an interface with non-laid out methods in another package? Or am I thinking of this problem in a non-idiomatic way?

+6
source share
1 answer

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

 type Adapter struct { accounting.IAdapter } 

I can do nothing with the adapter to provide my own implementation of the IAdapter.getInvoice () method.

This trick will not help you.

If you do not want other packages to use the accountingsystem.Adapter system directly, then make the type non-return and add a function to register the adapter using 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() } 
+8
source

Source: https://habr.com/ru/post/976213/


All Articles