Heim > Backend-Entwicklung > Golang > Gibt es eine Möglichkeit, (generische) Typparameter einzuschränken?

Gibt es eine Möglichkeit, (generische) Typparameter einzuschränken?

王林
Freigeben: 2024-02-09 13:18:19
nach vorne
461 Leute haben es durchsucht

Gibt es eine Möglichkeit, (generische) Typparameter einzuschränken?

PHP-Editor Youzi hat eine häufig gestellte Frage besprochen: Gibt es eine Möglichkeit, (universelle) Typparameter einzuschränken? In PHP müssen wir den Parametern von Funktionen oder Methoden häufig Typbeschränkungen auferlegen, um sicherzustellen, dass die übergebenen Parameter bestimmte Typanforderungen erfüllen. Derzeit gibt es jedoch keine direkte Möglichkeit, generische Typparameter wie Arrays oder Objekte einzuschränken. Wir können jedoch Einschränkungen für allgemeine Typparameter implementieren, indem wir eine strengere Typprüfungslogik schreiben, um die Richtigkeit und Konsistenz der Parameter sicherzustellen. In diesem Artikel untersuchen wir verschiedene Möglichkeiten zur Implementierung generischer Typparametereinschränkungen sowie deren Vor- und Nachteile.

Frageninhalt

Ich habe gerade angefangen, Generika zu lernen. Ich versuche also, einen Treiber für eine benutzerdefinierte Datenbank zu verallgemeinern, die auf einigen Protobuf-Nachrichten ausgeführt wird.

Ich würde gerne einen Weg finden, meinen generischen Typ weiter einzuschränken, aber als Zeiger, d. h. sicherstellen (dem Compiler mitteilen), dass die Einschränkung e eine andere Methode implementiert.

Zuerst habe ich die Entitäten eingeschränkt, die die Datenbank verarbeiten kann.

type entity interface {
   pb.msga | pb.msgb | pb.msgc
}
Nach dem Login kopieren

Dann wurde eine gemeinsame Schnittstelle geschrieben, die die Funktionalität der Datenbank beschreibt, damit sie von verschiedenen Diensten verwendet werden kann, die ihre eigenen Rohnachrichten verarbeiten:

type db[e entity] interface {
   get(...) (e, error)
   list(...) ([]e, error)
   ...
}
Nach dem Login kopieren

So weit so gut. Allerdings möchte ich diese Entitäten bei der Kommunikation mit der Datenbank auch (de)serialisieren, damit sie über das Netzwerk gesendet, geklont und zusammengeführt werden können. Dinge wie diese:

func encode[e entity](v *e) ([]byte, error) {
   return proto.marshal(v)
}
Nach dem Login kopieren

Der obige Code gibt jedoch den folgenden Fehler aus:

cannot use val (variable of type *e) as type protoreflect.protomessage in argument to proto.marshal: *e does not implement protoreflect.protomessage (type *e is pointer to type parameter, not type parameter)
Nach dem Login kopieren

Das Problem ist die proto.marshal 需要实体(*e)来实现 proto.message 接口,即 protoreflect()-Methode, die alle meine Entitätstypen implementieren, aber sie ist nicht eingeschränkt und kann vom Compiler nicht abgeleitet werden.

Ich habe auch versucht, die Entität wie folgt zu definieren:

type Entity interface {
   *pb.MsgA | *pb.MsgB | *pb.MsgC
   proto.Message
}
Nach dem Login kopieren

Aber das fühlt sich nicht richtig an, abgesehen von der Tatsache, dass ich einige zusätzliche Schutzoperationen durchführen muss, um die proto.messages zu instanziieren, auf die der Entitätszeiger verweist.

Lösung

Sie können dies tun:

func encode[m interface { *e; proto.message }, e entity](v m) ([]byte, error) {
    return proto.marshal(v)
}
Nach dem Login kopieren

Wenn Sie eine prägnantere Syntax als oben wünschen, können Sie die Nachrichtenbeschränkung aufheben:

type Message[E Entity] interface {
    *E
    proto.Message
}

func Encode[M Message[E], E Entity](v M) ([]byte, error) {
    return proto.Marshal(v)
}
Nach dem Login kopieren

https://www.php.cn/link/20ba66f905957b34253d9d7abde919f3

Das obige ist der detaillierte Inhalt vonGibt es eine Möglichkeit, (generische) Typparameter einzuschränken?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
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
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage