Dieser Artikel vermittelt Ihnen relevantes Wissen über PHP. Als nächstes werden wir uns mit der Situation hinter Generika und PHP befassen, um zu verstehen, warum Generika noch nicht unterstützt werden hilft allen.
Empfohlene Studie: „PHP-Tutorial“
Wir werden uns eingehend mit Generika befassen und was sich hinter PHP abspielt. Es ist sehr interessant und wichtig zu verstehen, warum Generika in PHP noch nicht als erstklassige Bürger unterstützt werden.
Mal sehen.
Es gibt keine Generika in PHP. Das ist das Fazit zum letztjährigen Nikita. Das ist einfach nicht machbar.
Um zu verstehen, warum Nikita das gesagt hat, müssen wir uns ansehen, wie Generika implementiert werden. Im Allgemeinen gibt es drei mögliche Ansätze; Programmiersprachen, die Generika unterstützen, verwenden meist einen dieser drei Ansätze.
Das erste nennt sich monomorphe Generika. Kehren wir zum ersten Artikel dieser Serie zurück, in dem ich dieses Sammlungsbeispiel gezeigt habe:
class StringCollection extends Collection { public function offsetGet(mixed $key): string { /* … */ } } class UserCollection extends Collection { public function offsetGet(mixed $key): User { /* … */ } }
Ich habe erklärt, dass wir Implementierungen von Sammlungsklassen für jeden Sammlungstyp, den wir benötigen, manuell erstellen können. Der Arbeitsaufwand wird enorm sein und es wird eine Menge Code geben, aber es wird funktionieren.
Monomorphe Generika machen genau das, aber automatisch im Hintergrund. Zur Laufzeit weiß PHP nichts über die generische Collection-Klasse, sondern über zwei oder mehr spezifische Implementierungen:
$users = new Collection<User>(); // Collection_User $slugs = new Collection<string>(); // Collection_string
Monomorphe Generika sind ein absolut gültiger Ansatz. Rust verwendet sie beispielsweise. Ein Vorteil besteht darin, dass es eine Reihe von Leistungsverbesserungen gibt, da zur Laufzeit keine generischen Typprüfungen mehr stattfinden und diese Prüfungen daher vor der Ausführung des Codes separat erfolgen.
Aber das bringt uns sofort zum Problem der monomorphen Generika in PHP. PHP verfügt nicht über einen expliziten Kompilierungsschritt, der eine generische Klasse in mehrere konkrete Implementierungen aufteilt, wie dies bei Rust der Fall ist. Das Fazit lautet: Monomorphe Generika erfordern zwar ziemlich viel Speicher, da Sie mehrere Kopien derselben Klasse erstellen, aber dort gibt es einige Unterschiede. Für kompilierte Rust-Binärdateien stellt dies möglicherweise kein großes Problem dar, aber es ist ein ernstes Problem für PHP-Code, der von einem zentralen Punkt (Server) aus ausgeführt wird und möglicherweise Hunderte oder Tausende von Anfragen pro Sekunde verarbeitet.
Die nächste Möglichkeit besteht darin, Generika zu reifizieren. Dies ist eine Implementierung, bei der die generische Klasse unverändert bleibt und die Typinformationen zur Laufzeit dynamisch ausgewertet werden. C# und Kotlin implementieren Generika, die dem aktuellen PHP-Typsystem am nächsten kommen, da PHP alle Typprüfungen zur Laufzeit durchführt. Das Problem hierbei ist, dass eine umfangreiche Umgestaltung des Kerncodes erforderlich ist, damit materialisierte Generika funktionieren, und Sie können sich vorstellen, dass mit zunehmender Typprüfung zur Laufzeit ein gewisser Leistungsaufwand zunehmen wird.
Das bringt uns zur letzten Option: Generika zur Laufzeit vollständig ignorieren. Es ist, als ob sie nicht vorhanden wären; schließlich kann eine generische Implementierung einer Sammlungsklasse ohnehin alle Arten von Eingaben verarbeiten.
Wenn wir also alle generischen Typprüfungen zur Laufzeit ignorieren, gibt es kein Problem.
Na ja, nicht so schnell. Das Ignorieren generischer Typen zur Laufzeit – das nennt man übrigens Typlöschung, und Java und Python machen das – verursachte einige Probleme für PHP.
Ein Beispiel: PHP verwendet nicht nur Typen zur Validierung, sondern auch Typinformationen, um Werte dynamisch von einem Typ in einen anderen umzuwandeln – das ist das Typ-Jonglieren, das ich im ersten Artikel dieser Serie erwähnt habe:
function add(int $a, int $b): int { return $a + $b; } add('1', '2') // 3;
Wenn PHP Wenn der generische Typ dieser „String“-Sammlung ignoriert wird und wir versehentlich eine Ganzzahl hinzufügen, werden wir nicht gewarnt, wenn der generische Typ entfernt wird:
$slugs = new Collection<string>(); $slugs[] = 1; // 1 不会被转换为 '1'
Typlöschung Das zweite und wichtigere Problem – und vielleicht hatten Sie es auch Ich schreie mittlerweile auf deinen Bildschirm – ist das so, dass Genres verschwinden? Wenn generische Typen zur Laufzeit entfernt werden, warum fügen wir sie dann hinzu?
Dies ist in Java und Pyton sinnvoll, da alle Typdefinitionen überprüft werden, bevor der Code mit dem statischen Analysator ausgeführt wird. Java führt beispielsweise beim Kompilieren Ihres Codes einen integrierten statischen Analysator aus, was PHP überhaupt nicht tut: Es gibt keinen Kompilierungsschritt und schon gar keinen integrierten statischen Typprüfer.
Andererseits kommen alle Vorteile der Typprüfung, die wir in früheren Artikeln besprochen haben, nicht aus dem integrierten Laufzeit-Typprüfer von PHP. Wir führen den Code bereits aus, als uns die Typprüfung von PHP mitteilt, dass ein Problem vorliegt. Ein Typfehler führt im Wesentlichen zum Absturz unseres Programms.
Stattdessen kommt der größte Mehrwert der Typprüfung von statischen Analysatoren, die nicht erfordern, dass wir den Code ausführen. Solange Programmierer ausreichende Typinformationen bereitstellen, haben sie gute Chancen sicherzustellen, dass zur Laufzeit keine Typfehler auftreten. Das bedeutet nicht, dass Ihr Code keine Fehler enthalten darf, aber es ist möglich, PHP-Code zu schreiben, der vollständig statisch überprüft ist und zur Laufzeit keinerlei Fehler erzeugt. Das Fazit: Wir gewinnen alle statischen Erkenntnisse beim Schreiben von Code; dies ist der wertvollste Teil eines jeden Typsystems, unabhängig von der Typprüfung zur Laufzeit.
Brauchen wir also wirklich eine Laufzeittypprüfung? Denn dies ist der Hauptgrund, warum Sie in PHP derzeit keine Generika hinzufügen können: Die Validierung generischer Typen zur Laufzeit ist für PHP zu komplex oder zu ressourcenintensiv.
Originaladresse: https://stitcher.io/blog/generics-in-php-3
Übersetzungsadresse: https://learnku.com/php/t/66486
Empfohlenes Lernen: „PHP Video-Tutorial》
Das obige ist der detaillierte Inhalt vonLassen Sie uns analysieren, warum Generics in PHP nicht verwendet werden können. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!