Heim  >  Artikel  >  Backend-Entwicklung  >  Wie kann ich einen Teil der Schnittstellen effizient mit Instanzen eines konkreten Typs in Golang füllen und gleichzeitig die Typsicherheit gewährleisten und mögliche Paniken vermeiden?

Wie kann ich einen Teil der Schnittstellen effizient mit Instanzen eines konkreten Typs in Golang füllen und gleichzeitig die Typsicherheit gewährleisten und mögliche Paniken vermeiden?

Patricia Arquette
Patricia ArquetteOriginal
2024-10-26 03:59:02203Durchsuche

How can I efficiently fill a slice of interfaces with instances of a concrete type in Golang, while ensuring type safety and avoiding potential panics?

Generische Füllfunktion für Slices von Schnittstellen und konkreten Typen

In Golang ist es möglich, generische Funktionen mithilfe von Generics zu definieren. Beim Umgang mit Schnittstellen-Slices und konkreten Typen besteht eine häufige Aufgabe darin, alle Elemente des Slice mit einem konkreten Typ zu initialisieren. Betrachten Sie die folgende Funktion, die darauf abzielt, ein Segment von Zeigern auf einen Typ X mit neuen Instanzen von X zu füllen:

<code class="go">func Fill[X any](slice []*X){
   for i := range slice {
      slice[i] = new(X)
   }
}</code>

Diese Funktion funktioniert wie erwartet für Slices jeden Typs. Es treten jedoch Herausforderungen auf, wenn versucht wird, dieses Verhalten auf Schnittstellensegmente auszudehnen und einen konkreten Typ für das Element (Y) anzugeben.

<code class="go">func Fill[X, Y any](slice []X){
   for i := range slice {
      slice[i] = new(Y) // not work!
   }
}</code>

Wenn sowohl X als auch Y auf „beliebig“ beschränkt werden, ändert sich die Beziehung zwischen Schnittstellen und Implementierern ist verloren. Der Compiler behandelt X und Y als separate Typen und verhindert so Zuweisungen zwischen ihnen innerhalb des Funktionskörpers.

Um dieses Problem zu lösen, kann eine explizite Behauptung verwendet werden:

<code class="go">func Fill[X, Y any](slice []X) {
    for i := range slice {
        slice[i] = any(*new(Y)).(X)
    }
}</code>

Dieser Ansatz kann jedoch Panik, wenn Y X nicht implementiert, wie im Fall von sync.Mutex (ein Zeigertyp), der sync.Locker implementiert. Da außerdem der Nullwert für einen Zeigertyp Null ist, bietet diese Methode keine wesentliche Verbesserung gegenüber der Verwendung von make([]X, n), das das Slice ebenfalls mit Nullwerten initialisiert.

Eine effektivere Lösung besteht darin, eine Konstruktorfunktion anstelle eines zweiten Typparameters zu verwenden:

<code class="go">func Fill[X any](slice []X, f func() X) {
    for i := range slice {
        slice[i] = f()
    }
}</code>

Diese Funktion benötigt einen zusätzlichen Parameter f, eine Funktion, die eine Instanz von X zurückgibt. Dies ermöglicht mehr Flexibilität und unterstützt das Füllen von Schnittstellen mit konkreten Typen. Um beispielsweise einen Abschnitt von sync.Locker mit sync.Mutex-Elementen zu initialisieren, kann der folgende Code verwendet werden:

<code class="go">xs := make([]sync.Locker, 10)
Fill(xs, func() sync.Locker { return &sync.Mutex{} })</code>

Durch die Verwendung dieses Ansatzes können Schnittstellenabschnitte effizient mit Instanzen eines Betons gefüllt werden Typ, der eine praktische und typsichere Lösung bietet.

Das obige ist der detaillierte Inhalt vonWie kann ich einen Teil der Schnittstellen effizient mit Instanzen eines konkreten Typs in Golang füllen und gleichzeitig die Typsicherheit gewährleisten und mögliche Paniken vermeiden?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn