Einige PHPer denken über die Umstellung auf Go oder Java nach. Lassen Sie uns einen einfachen Vergleich zwischen diesen beiden Sprachen anstellen. Dieser Artikel dient nur als Referenz!
Go-Sprache
Im Vergleich zu Java wird die Go-Sprache in Maschinencode kompiliert und dann direkt ausgeführt. Ähnlich wie die C-Sprache. Da es keine virtuelle Maschine gibt, unterscheidet es sich stark von Java. Es ist objektorientiert und bis zu einem gewissen Grad nicht nur eine neue C-Sprache mit automatischer Speicherbereinigung. Aus der Sicht eines Java-Programmierers gibt es Dinge, die so unterschiedlich sind, dass das Erlernen der Go-Sprache äußerst herausfordernd wird und dabei hilft, ein tieferes Verständnis der Konstrukte der Programmiersprache sowie von Objekten, Klassen und allen anderen Vorgängen in den Sprachkomponenten zu erlangen, selbst bei Java .
Ich meine, wenn Sie die objektorientierte Implementierung in der Go-Sprache verstehen, dann werden Sie auch die verschiedenen Implementierungen dieser Dinge in der Java-Sprache verstehen.
Ob Garbage Collection verwendet werden soll
Der Speicherverwaltungsteil ist in Programmiersprachen von entscheidender Bedeutung. Mit der Assemblersprache können Sie alles tun, oder besser gesagt, Sie werden aufgefordert, alles zu tun. Die C-Standardbibliothek stellt einige grundlegende Funktionen für die Speicherverwaltung bereit, erfordert jedoch immer noch, dass Sie diese manuell freigeben, nachdem Sie malloc aufgerufen haben, um Speicher zuzuweisen. Mit C++, Python, Swift und Java entstand eine automatisierte Speicherverwaltungstechnologie. Go-Sprache ist auch eine davon.
Für Java und andere JVM-Sprachen (einschließlich der JVM-Implementierung von Python) wird der Speicher von der JVM verwaltet. Die JVM verfügt über eine sehr ausgereifte Garbage Collection. Die Garbage Collection läuft immer in einem oder mehreren Threads – manchmal werden diese Worker-Threads angehalten, um diese nicht erreichbaren Objekte zu markieren, sie zu löschen und die erkannten Objekte zu verteilen zusammengedrückt. Sie müssen sich nur um die Leistung kümmern.
Go-Sprache verwendet diese Methode ebenfalls, es gibt jedoch immer noch einige subtile Unterschiede. Die Go-Sprache hat keine Referenzen, aber Zeiger. Dieser Unterschied ist sehr wichtig. Die Go-Sprache kann mit zusätzlichem C-Code integriert werden. Aus Leistungsgründen werden zur Laufzeit keine Referenzen registriert. Der eigentliche Zeiger ist für das laufende System transparent. Der zugewiesene Speicher kann weiterhin analysiert werden, um Erreichbarkeitsinformationen zu sammeln, und nutzlose Objekte können weiterhin markiert und gelöscht werden, der Speicher kann jedoch nicht zur Komprimierung an einen anderen Ort verschoben werden.
Die Go-Sprache verfügt über eine Speicherbereinigung, ist aber kein vollständiger GC wie Java, da sie den Speicher nicht komprimiert. Das ist nicht unbedingt eine schlechte Sache. Denn das ist sinnvoll, damit der Server lange läuft, ohne dass es zu einer Speicherfragmentierung kommt. Einige JVM-Garbage Collectors überspringen auch den Komprimierungsschritt, um GC-Pausen beim Löschen der alten Generation zu reduzieren, und verwenden die Komprimierung nur als letzten Ausweg. Dieser letzte Ausweg ist in Go nicht implementiert, was in seltenen Fällen zu Problemen führen kann. Wenn Sie diese Sprache lernen, ist es unwahrscheinlich, dass Sie auf dieses Problem stoßen.
Lokale Variablen
In der Java-Sprache werden lokale Variablen (und manchmal Objekte in neueren Versionen) auf dem Stapel gespeichert. Dies gilt auch für C, C++ und andere Sprachen, die den Aufrufstapel selbst implementieren. Go ist keine Ausnahme, es sei denn, Sie geben von einer Funktion einfach einen Zeiger auf eine lokale Variable zurück. Dies ist ein schwerwiegender Fehler in der C-Sprache. Für Go stellt der Go-Compiler fest, dass das zugewiesene „Objekt“ (ich werde später erklären, warum hier Anführungszeichen verwendet werden) der Methode entkommt und weist es (Speicher) entsprechend zu, sodass dieses „Objekt“ in der Funktion noch am Leben ist nach der Rückkehr und der Zeiger darauf zeigt nicht auf veralteten Speicher mit unzuverlässigen Daten.
Abschlüsse
Sie können eine Funktion innerhalb einer Funktion schreiben und dann diese Funktion zurückgeben, genau wie eine funktionale Sprache (Go ist eine funktionale Sprache), und dann die lokale Variable ist eine Abschlussvariable in dieser Funktion.
Funktionsrückgabewert
Eine Funktion kann nicht nur einen einzelnen Wert, sondern auch mehrere Werte zurückgeben. Dies scheint eine schlechte Praxis ohne faire Verwendung zu sein. Dies gilt sowohl für Python als auch für Perl. In manchen Situationen ist die Rückgabe mehrerer Werte hilfreich. Es wird hauptsächlich für Rückgabewerte und „Null“ oder Fehlercodes verwendet. Auf diese Weise wird die frühere Gewohnheit, Fehler in den Rückgabetyp zu kodieren (normalerweise wird -1 als Fehlercode zurückgegeben, wie bei einem C-Standardbibliotheksaufruf, und andere nicht negative Werte, die andere Bedeutungen darstellen), durch diese besser lesbare Methode ersetzt .
Objektorientiert
Durch die Behandlung von Abschlüssen und Funktionen als erstklassige Bürger kann Go mindestens so objektorientiert sein wie JavaScript. Tatsächlich verfügt Go jedoch über Schnittstellen und Strukturen und kann mehr. Aber Schnittstellen und Strukturen sind keine echten Klassen, sondern Werttypen. Sie werden als Wert übergeben, und unabhängig davon, wo sie im Speicher gespeichert sind, handelt es sich bei den von ihnen gespeicherten Daten lediglich um reine Daten, ohne Objektheader oder ähnliches. Strukturen in Go sind Strukturen in C sehr ähnlich – sie können beide Felder enthalten, aber sie können nicht voneinander erben oder Methoden enthalten. Die objektorientierte Implementierung unterscheidet sich geringfügig.
Anstatt die Methode in die Klassendefinition zu stopfen, können Sie die Struktur angeben, wenn Sie die Methode selbst definieren. Strukturen können auch andere Strukturen enthalten. Wenn das Feld, auf das Sie verweisen möchten, keinen Namen hat, können Sie es über seinen Typ referenzieren, der implizit auch zum Namen des Feldes wird. Oder solange dieses Feld oder diese Methode zur Struktur der obersten Ebene gehört, können Sie darauf verweisen
Wenn Sie die Struktur angeben möchten, die die Methode aufrufen kann, können Sie sie selbst über die Struktur angeben oder darauf verweisen ein Zeiger auf die Struktur. Wenn eine Methode auf eine Struktur angewendet wird, erhält die Methode eine Kopie der aufrufenden Struktur (die als Wert übergeben wird). Wenn die Methode auf einen Zeiger auf eine Struktur angewendet wird, wird der Zeiger übergeben (ähnlich wie bei der Übergabe per Referenz). Im letzteren Fall kann die Methode auch die Struktur mutieren (in diesem Sinne ist die Struktur kein Werttyp, da Werttypen unveränderlich sind). Beide können verwendet werden, um die Anforderungen der Schnittstelle zu erfüllen.
Gos Syntax ist außerdem toleranter gegenüber Strukturen und Zeigern. In C können Sie b.a verwenden, um auf das a-Feld einer Struktur zuzugreifen, die Sie besitzen. Für Zeiger auf Strukturen in C müssen Sie b->a verwenden, um auf dieselben Felder zuzugreifen. b.a meldet einen Fehler bei der Verwendung von Zeigern. Go denkt, dass das Schreiben von b->a bedeutungslos ist (ja, das ist es, was es bedeutet). Warum lässt der ->-Operator den Code unübersichtlich aussehen, wenn der Operator überladen sein kann? Die Struktur kann auf diese Weise auf Felder zugreifen, daher sollte der Zugriff auch auf diese Weise über Zeiger erfolgen, was sehr logisch ist.
Der Typ bezieht sich auf die Variable, nicht auf das Objekt
Deshalb setze ich „Objekt“ in Anführungszeichen. Wenn Go eine Struktur speichert, ist sie ein Teil des Speichers. Sie hat keinen Objektheader. Tatsächlich enthält die Variable den Typ des Werts. Wenn die Variable ein Strukturtyp ist, wissen wir ihn bereits zur Kompilierungszeit. Wenn es sich bei der Variablen um einen Schnittstellentyp handelt, zeigt die Variable auf ihren Wert und verweist auf den tatsächlichen Typ des Werts.
Schnittstellen implementieren
Schnittstellen sind in Go sehr einfach und sehr komplex. Eine Schnittstelle deklariert eine Reihe von Methoden, die Strukturen implementieren müssen, wenn sie mit der Schnittstelle kompatibel sein wollen. Das Erben von Schnittstellen ist dasselbe wie das Erben von Strukturen. Das Seltsame daran ist, dass Sie, wenn eine Struktur eine Schnittstelle implementiert, diese nicht explizit angeben müssen. Tatsächlich ist es nicht die Schnittstelle, die die Schnittstelle implementiert, sondern dieser Funktionssatz, der die Struktur oder den Zeiger auf die Struktur als Empfänger verwendet. Wenn alle Funktionen der Schnittstelle implementiert sind, dann implementiert diese Struktur die Schnittstelle. Wenn einige Funktionen nicht implementiert sind, ist die Implementierung unvollständig.
Warum brauchen wir das Schlüsselwort „implements“ in Java, aber nicht in Go? Go braucht es wirklich nicht, weil es vollständig kompiliert ist und es keinen Klassenlader wie Java gibt, der kompilierten Code zur Laufzeit separat lädt. Wenn eine Struktur eine Schnittstelle implementieren soll, dies aber nicht tut, wird dies zur Kompilierungszeit erkannt und es ist nicht erforderlich, explizit anzugeben, ob die Schnittstelle die Schnittstelle implementiert. Sie können dies mithilfe der Reflektion von Go implementieren, was einen Laufzeitfehler verursacht, aber in jedem Fall hat die Deklaration des Schlüsselworts „implements“ keine Auswirkung.
Threads und Warteschlangen
Go-Sprache verfügt über integrierte Threads und Warteschlangen. Sie werden Coroutinen und Kanäle genannt. Um eine Coroutine zu starten, müssen Sie lediglich die Go-Funktion call() schreiben, die in einem anderen Thread gestartet wird. Obwohl es in der Go-Standardbibliothek Methoden oder Funktionen zum Sperren von „Objekten“ gibt, verwendet die native Multithread-Programmierung Kanäle. Der Kanal ist ein in Go integrierter Typ, bei dem es sich um einen First-In-First-Out-Kanal mit fester Größe eines anderen Typs handelt. Sie können einen Wert in den Kanal übertragen und die Coroutine kann den Wert aus dem Kanal abrufen. Wenn der Kanal voll ist, wird durch Drücken blockiert; wenn der Kanal leer ist, wird durch Ziehen blockiert.
Es gibt Fehler, aber keine Ausnahmen in Go
Go verfügt tatsächlich über eine Ausnahmebehandlung, wird aber nicht wie in Java verwendet. Ausnahmen werden „Panik“ genannt und werden verwendet, wenn im Code eine echte Panik vorliegt. Aus Sicht der Java-Regeln ähnelt „Panic“ einigen Ausnahmen, die mit „...Error“ enden. Dieser Zustand wird von einem Systemaufruf zurückgegeben, wenn eine Ausnahmeinstanz oder ein Fehler vorliegt, der behandelt werden kann, und von Anwendungsfunktionen wird erwartet, dass sie diesen Zustand in einem ähnlichen Muster behandeln.
Es gibt kein „finally“, „defer“ ersetzt es
Die eng gekoppelte Ausnahmebehandlung ist eine Funktion, die Java zusammen mit der Funktion „try/catch/finally“ implementiert. In Java können Sie Code, der auf jeden Fall ausgeführt wird, in einen „finally“-Block einfügen. Go bietet das Schlüsselwort „defer“, mit dem Sie eine Funktion angeben können, die aufgerufen werden soll, bevor die Methode zurückkehrt (auch wenn die Methode in Panik gerät). Die Verwendung von Defer zur Lösung des oben genannten Problems macht es weniger anfällig für Missbrauch. Nach einem verzögerten Funktionsaufruf können Sie keinen ausführbaren Code mehr schreiben. Aber in Java können Sie sogar eine Return-Anweisung in den Final-Block schreiben oder eine sehr verwirrende Try-Anweisung sehen, die verwendet wird, um den im Final-Block auszuführenden Code zu verarbeiten, der ebenfalls eine Ausnahme auslösen kann. Go tendiert zu ersterem.
Insgesamt ist Go eine interessante Sprache. Es ist kein Ersatz für Java, auch nicht auf sprachlicher Ebene. Java und Go erfüllen nicht die gleiche Art von Aufgaben – Java ist eine Entwicklungssprache auf Unternehmensebene und Go ist eine Programmiersprache auf Systemebene.
Empfohlenes Java-Video-Tutorial: JAVA-Video-Tutorial
Empfohlenes Go-Video-Tutorial: Go-Video-Tutorial
Das obige ist der detaillierte Inhalt vonPHP in Go oder Java konvertieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!