Schnittstellen mit nicht exportierten Methoden aus anderen Paketen implementieren
In Go dienen Schnittstellen als Verträge, die eine Reihe von Methoden definieren, die von implementiert werden müssen jeder Typ, der daran haftet. Normalerweise werden die Methoden einer Schnittstelle exportiert, um den Zugriff von anderen Paketen aus zu ermöglichen. Es kann jedoch Szenarien geben, in denen Sie bestimmte Implementierungen vor dem verbrauchenden Programm ausblenden müssen.
Betrachten Sie das folgende Beispiel, in dem wir eine Schnittstelle für den Zugriff auf das Buchhaltungssystem definieren:
package accounting import "errors" type IAdapter interface { GetInvoice() error }
Ausblenden Bei bestimmten Implementierungen machen wir die Schnittstellenmethoden nicht exportiert und führen Wrapper-Funktionen in das Basispaket ein, die die entsprechende Implementierung über eine aufrufen Adapter:
var adapter IAdapter func SetAdapter(a IAdapter) { adapter = a } func GetInvoice() error { if (adapter == nil) { return errors.New("No adapter set!") } return adapter.GetInvoice() }
Obwohl dieser Ansatz vielversprechend erscheint, tritt beim Versuch, die Schnittstelle in einem anderen Paket zu implementieren, ein Problem auf. Der Compiler beschwert sich darüber, dass er die nicht exportierte GetInvoice-Methode nicht sehen kann.
Dieses Problem ist auf die Art und Weise zurückzuführen, wie Schnittstellen in Go funktionieren. Eine Schnittstelle besteht nur aus den Methodensignaturen, ohne dass deren Implementierung bekannt ist. Wenn ein Typ eine Schnittstelle implementiert, muss er alle Methoden mit denselben Signaturen wie die Schnittstelle verfügbar machen.
Um diese Einschränkung zu überwinden, können wir anonyme Strukturfelder verwenden:
type Adapter struct { accounting.IAdapter }
Dies ermöglicht Wir können die Schnittstelle in einem anderen Paket implementieren, indem wir sie anonym einbetten. Wir können jedoch keine benutzerdefinierten Implementierungen für die nicht exportierten Methoden bereitstellen.
Eine idiomatischere Lösung wäre die Bereitstellung einen nicht exportierten Adapter und stellen eine Registrierungsfunktion im Basispaket bereit:
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() }
Dieser Ansatz stellt sicher, dass der Adapter verborgen bleibt, ermöglicht aber dennoch die Registrierung einer entsprechenden Implementierung.
Das obige ist der detaillierte Inhalt vonWie kann ich eine Schnittstelle mit nicht exportierten Methoden aus einem anderen Go-Paket implementieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!