Heim >Backend-Entwicklung >Golang >Wie kann ich eine generische Go-Funktion erstellen, die einen Zeiger auf eine Schnittstellenimplementierung akzeptiert?

Wie kann ich eine generische Go-Funktion erstellen, die einen Zeiger auf eine Schnittstellenimplementierung akzeptiert?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-21 05:25:14183Durchsuche

How Can I Create a Generic Go Function That Accepts a Pointer to an Interface Implementation?

Generischer Zeiger auf Schnittstellenimplementierung

In Go kann die Definition einer generischen Funktion, die einen Zeiger auf eine Schnittstelle akzeptiert, eine Herausforderung sein. Betrachten Sie eine Schnittstelle A mit einer SomeMethod():

type A interface {
  SomeMethod()
}

Und nehmen wir an, es gibt eine Implementierung von A als Strukturzeiger:

type Aimpl struct {}

func (a *Aimpl) SomeMethod() {}

Um einen generischen Funktionshandler zu erstellen, der eine Funktion übernimmt mit einem A-Parameter wäre es wünschenswert zu definieren:

func Handler[T A](callback func(result T)) {
  // Essentially what I'd like to do is result := &Aimpl{} (or whatever T is)
  callback(result)
}

Es gibt jedoch einige Einschränkungen Bedenken Sie.

Versuch mit einem beliebigen Typparameter

Zunächst scheint es möglich zu sein, eine Schnittstelle mit einem Typparameter zu definieren, um Zeigerimplementierungen zu ermöglichen:

type MyA[T any] interface{
  A
  *T
}

Dies schlägt jedoch mit dem folgenden Fehler fehl:

result does not implement interface. It's a pointer to a type, not a type

Lösung: Typ parametrisiert Schnittstelle

Um dies zu umgehen, kann die Schnittstelle mit einem Typparameter deklariert werden, der erfordert, dass der implementierende Typ ein Zeiger auf seinen Typparameter ist:

type A[P any] interface {
    SomeMethod()
    *P
}

Mit dieser Schnittstelle Die Handler-Funktion kann geändert werden:

func Handler[P any, T A[P]](callback func(result T)) {
    result := new(P)
    callback(result)
}

Jetzt kann der Code Handler als aufrufen erwartet:

Handler(func(a *Aimpl) { fmt.Printf("%#v\n", a) })

Alternative mit Interface Wrapper

Wenn die Definition von A nicht geändert werden kann, besteht ein alternativer Ansatz darin, sie in eine benutzerdefinierte Schnittstelle zu packen:

type MyA[P any] interface {
    A
    *P
}

Und ändern Sie die Handler-Funktion entsprechend:

func Handler[P any, T MyA[P]](callback func(result T)) {
    result := new(P)
    callback(result)
}

Beide Lösungen ermöglichen die Erstellung generischer Funktionen Akzeptieren Sie Zeiger auf Schnittstellenimplementierungen.

Das obige ist der detaillierte Inhalt vonWie kann ich eine generische Go-Funktion erstellen, die einen Zeiger auf eine Schnittstellenimplementierung akzeptiert?. 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