Ich sehe diese Begriffe in der Programmierung überall herumschwirren und habe eine vage Vorstellung davon, was sie bedeuten. Eine Suche zeigt mir, dass solche Dinge in der Tat überall auf Stack Overflow gefragt wurden. Soweit ich weiß, unterscheidet sich die statische/dynamische Typisierung in Sprachen geringfügig von der starken/schwachen Typisierung, aber was der Unterschied ist, entzieht sich mir. Verschiedene Quellen scheinen unterschiedliche Bedeutungen zu verwenden oder die Begriffe sogar austauschbar zu verwenden. Ich kann nirgends eine Quelle finden, die über beide Begriffe spricht und den Unterschied deutlich macht. Es wäre schön, wenn jemand dies hier für mich und den Rest der Welt klar formulieren könnte.
Antworten
Zu viele Anzeigen?Von Scott's Pragmatik der Programmiersprachen , 3. Auflage Seite 291, haben wir
Bei der Typüberprüfung wird sichergestellt, dass ein Programm den Kompatibilitätsregeln der Sprache einhält. Ein Verstoß gegen die Regeln wird als als Typkonflikt bezeichnet. Eine Sprache gilt als stark typisiert wenn es in einer Weise, die die Sprachimplementierung erzwingen kann, die Anwendung von Operationen auf Anwendung einer Operation auf ein Objekt, das diese Operation nicht unterstützen soll diese Operation zu unterstützen. Eine Sprache gilt als statisch typisiert wenn sie stark typisiert ist und eine Typüberprüfung zur Kompilierzeit durchgeführt werden kann Zeit durchgeführt werden kann. Im engsten Sinne des Wortes sind nur wenige Sprachen statisch typisiert. In der Praxis wird der Begriff oft für Sprachen verwendet, in denen der größte Teil der Typprüfung zur Kompilierzeit durchgeführt werden kann, und der Rest kann während der Laufzeit durchgeführt werden kann.
Ein paar Beispiele: Ada ist stark typisiert, und zum größten Teil statisch typisiert (bestimmte Typeinschränkungen müssen zur Laufzeit überprüft werden). Zeit überprüft werden). Eine Pascal-Implementierung kann auch den größten Teil ihrer Typüberprüfung durchführen zur Kompilierzeit durchführen, obwohl die Sprache nicht ganz stark typisiert ist: ungetaggte Variantensätze (die in Abschnitt 7.3.4 besprochen werden) sind ihre einzige Schlupfloch. C89 ist deutlich stärker typisiert als sein Vorgängerdialekte, aber immer noch deutlich weniger stark typisiert als Pascal. Zu seinen Lücken gehören Unions, Unterprogramme mit variabler Anzahl von Parametern, und die Interoperabilität von Zeigern und Arrays (wird Abschnitt 7.7.1 diskutiert). Implementierungen von C überprüfen selten etwas zur Laufzeit.
Die dynamische (Laufzeit-)Typüberprüfung ist eine Form der späten Bindung und findet in der Regel in Sprachen zu finden, die auch andere Probleme bis zur Laufzeit verzögern verzögern. Lisp und Smalltalk sind dynamisch (wenn auch stark) typisiert. Die meisten Skriptsprachen sind ebenfalls dynamisch typisiert; einige (z. B. Python und Ruby) sind stark typisiert. Sprachen mit dynamischem Scoping sind im Allgemeinen dynamisch typisiert (oder überhaupt nicht typisiert): Wenn der Compiler nicht das Objekt, auf das sich ein Name bezieht, nicht identifizieren kann, kann er normalerweise auch nicht auch nicht den Typ des Objekts bestimmen.
Vereinfacht ausgedrückt, bezieht sich die statische/dynamische Typisierung auf den Zeitpunkt der Typüberprüfung: Kompilierzeit bei statischer Typisierung und Laufzeit bei dynamischen Sprachen. Ebenso bezieht sich die starke/schwache Typisierung darauf, wie aggressiv eine Sprache ihr Typsystem durchsetzt.
Ich habe versucht, Scotts Beschreibung in ein hübsches Diagramm zu übersetzen, das ich unten veröffentlicht habe.
Statisch vs. dynamisch typisierte Sprachen
- Statisch typisierte Sprachen sind solche, in denen die Typüberprüfung zur Kompilierzeit erfolgt. Das bedeutet auch, dass in statisch typisierten Sprachen jede Variable einen Typ hat, der sich im Laufe des Programms nicht ändert. Nun, im Gegensatz dazu, dynamisch typisierte Sprachen sind solche, in denen die Typüberprüfung zur Laufzeit erfolgt und keine Typüberprüfung zur Kompilierzeit stattfindet; dies bedeutet also auch, dass in dynamisch typisierten Sprachen ein Typ mit einer Variablen verbunden sein kann oder nicht und wenn ein Typ zugeordnet ist, dann könnte es ein allgemeiner Typ wie "var" in JS sein, der sowohl für eine Zeichenkette als auch für eine Zahl gilt.
- "Implementierungen von dynamisch typgeprüften Sprachen verknüpfen im Allgemeinen jedes Laufzeitobjekt mit einem Typ-Tag (d.h. einem Verweis auf einen Typ), das seine Typinformationen enthält. Diese Laufzeittypinformationen (RTTI) können auch zur Implementierung von dynamischem Dispatch, Late Binding, Downcasting, Reflection und ähnlichen Funktionen verwendet werden."
- Auch wenn eine Sprache statisch typisiert ist, kann sie dennoch eine dynamisch typisierte Funktion haben, was im Grunde bedeutet, dass eine Art von Typüberprüfung zur Laufzeit ebenfalls stattfindet. Dies ist beim Gießen von Typen nützlich.
- "Eine Reihe nützlicher und gebräuchlicher Funktionen von Programmiersprachen können nicht statisch überprüft werden, wie z. B. Downcasting. Daher haben viele Sprachen sowohl eine statische als auch eine dynamische Typprüfung; die statische Typprüfung prüft, was sie kann, und die dynamische Prüfung prüft den Rest."
- "Einige Sprachen erlauben das Schreiben von Code, der nicht typsicher ist. In C zum Beispiel können Programmierer einen Wert zwischen zwei beliebigen Typen mit derselben Größe frei casten.
- Der Vorteil von "statisch" typisierten Sprachen ist, dass:
- Da der größte Teil der Typüberprüfung zur Kompilierzeit erfolgt, kann der Interpreter oder die Laufzeitumgebung mit voller Geschwindigkeit laufen, ohne sich um die Typen zu kümmern.
- Dies führt zu einer geringeren Anzahl von Laufzeitausnahmen oder Fehlern im Zusammenhang mit dem Typ, da die meisten Typprüfungen zur Kompilierzeit durchgeführt werden.
- Der Vorteil von "dynamisch" typisierten Sprachen ist, dass:
- Sie können zu einem extrem schnellen Prototyping beitragen, da der Entwickler das Typsystem nicht verstehen muss, so dass er einfach Variablen erstellen und ausführen kann, was zu einem sehr schnellen Prototyping führt.
- Liste der statisch und dynamisch typisierten Sprachen :
- Statisch:
- Java
- C (C ist eine statisch typisierte Sprache, aber im Vergleich zu Java weniger "stark" typisiert, da sie mehr implizite Konvertierungen zulässt)
- C++
- C#
- Dynamisch:
- PERL
- PHP
- Python
- JavaScript
- Rubinrot
- Statisch:
- Die Typenprüfung ist ein wichtiges Sicherheitsmerkmal. Angenommen, es gibt keine Typprüfung, und eine Methode akzeptiert ein Objekt des Typs "BankAccount", das eine Methode namens "creditAccount(BankAccountDetails)" hat, nun zur Laufzeit, wenn es keine Typprüfung gibt, dann kann ich ein Objekt meiner eigenen Klasse übergeben, die die gleiche Methode "creditAccount(BankAccountDetails)" hat, und es wird ausgeführt werden, wenn man bedenkt, dass wir über objektorientierte Sprache sprechen, weil OOP "Polymorphismus" unterstützt, und hier, was wir diskutieren, ist nichts anderes als "Polymorphismus". Eine objektorientierte Sprache (was im Grunde bedeutet, dass sie "Polymorphismus" unterstützt), die nicht über eine starke Typüberprüfung verfügt, kann also zu Sicherheitsproblemen führen.
Stark vs. schwach typisierte Sprachen
- Stark typisierte Sprachen sind solche, in denen implizite Konvertierungen nicht erlaubt sind, wenn dies zu Präzisionsverlusten führt. In Java kann man beispielsweise einen "int" in einen "long" umwandeln, da dies keinen Präzisionsverlust bedeutet, aber man kann nicht "implizit" einen "long" in einen "int" umwandeln, da dies einen Präzisionsverlust bedeuten würde. Im Gegensatz dazu sind in schwach typisierten Sprachen implizite Konvertierungen erlaubt, auch wenn es zu einem Verlust an Genauigkeit kommt.
- Ich denke, eine dynamisch typisierte Sprache kann auch eine stark typisierte Sprache sein, wenn sie "zur Laufzeit" keine impliziten Konvertierungen zulässt, bei denen es zu Präzisionsverlusten kommt.
Gute weiterführende Lektüre
Ich denke, die anderen Kollegen haben gute Arbeit geleistet, insbesondere bei der Erklärung des Unterschieds zwischen statischer und dynamischer Typisierung. Was jedoch die starke und schwache Typisierung betrifft, so muss man sagen, dass es unterschiedliche Auffassungen/Sichtweisen gibt.
Hier zwei Beispiele:
-
Manche sagen, dass Haskell stark typisiert ist, weil es nicht erlaubt ist, die jede Typkonvertierungen.
-
Andere (z.B. Darios Ansicht) sagen, dass eine Sprache, die absichtlich eine implizite Konvertierung von Zeichenketten in Zahlen erlaubt, schwach typisiert ist, aber auch andere nennen dies nur Duck Typing.
Beide Aussagen beleuchten nicht die entgegengesetzten Extreme eines Typensystems, sondern völlig unterschiedliche Aspekte. Ich schließe mich daher Herrn Ramseys Ansicht an, die Begriffe "stark" und "schwach" nicht zur Unterscheidung von Typsystemen zu verwenden.
Von Addison Wesley, Objektorientierte Analyse und Design mit Anwendungen , 3., Seite-66:
Die Konzepte der starken und schwachen Typisierung sowie der statischen und dynamischen Typisierung sind völlig unterschiedlich. Starke und schwache Typisierung bezieht sich auf Typ Konsistenz, während sich die statische und dynamische Typisierung auf den Zeitpunkt bezieht, zu dem Namen an Typen gebunden sind. Statische Typisierung (auch bekannt als statische Bindung oder frühes Binden) bedeutet, dass die Typen aller Variablen und Ausdrücke zum Zeitpunkt der Kompilierung festgelegt sind; dynamische Typisierung (auch späte Bindung) bedeutet, dass die Typen aller Variablen und Ausdrücke erst während der Laufzeit bekannt sind. Eine Sprache kann beides sein stark und statisch typisiert sein (Ada), stark typisiert aber unterstützend von dynamischer Typisierung (C++, Java), oder untypisiert, aber unterstützend von dynamischen Typisierung (Smalltalk).
Bei statisch typisierten Sprachen müssen Sie in der Regel die Variablentypen deklarieren, was dann zur Kompilierzeit überprüft wird, um Fehler zu vermeiden. Das Wort "statisch" in "statisch typisiert" bezieht sich auf die "statische Codeanalyse", d.h. die Untersuchung des Codes vor seiner Ausführung. Obwohl es für eine statisch typisierte Sprache möglich ist, den Typ der Variablen von der rechten Seite eines Ausdrucks oder von aktuellen Parametern abzuleiten, verlangen die meisten statisch typisierten Sprachen in der Praxis, dass Variablentypen explizit deklariert werden.
Dynamisch typisierte Sprachen verlangen im Allgemeinen nicht, dass Variablendeklarationen Typen haben, und sie leiten Variablentypen auf der Grundlage des Typs ab, der als Ergebnis der Auswertung der rechten Seite jeder Zuweisungsanweisung oder der aktuellen Parameter eines Funktionsaufrufs berechnet wird. Da die Variable während ihrer Lebensdauer mehrere Zuweisungen erhalten kann, kann sich ihr Typ im Laufe der Zeit ändern, weshalb sie als "dynamisch typisiert" bezeichnet wird. Außerdem muss die Laufzeitumgebung den aktuellen Typ für jede Variable verfolgen, so dass der Typ an den Wert und nicht an die Variablendeklaration gebunden ist. Dies kann als RTTI-System (Runtime Type Information) bezeichnet werden.
Elemente von statisch und dynamisch typisierten Sprachen können kombiniert werden. So unterstützt beispielsweise C# sowohl statisch als auch dynamisch typisierte Variablen, und objektorientierte Sprachen unterstützen im Allgemeinen das Downcasting der Typenhierarchie. Statisch typisierte Sprachen bieten in der Regel verschiedene Möglichkeiten zur Umgehung der Typprüfung, z. B. durch Casting, Reflexion und dynamische Aufrufe.
Strong vs. Weak Typing bezieht sich auf ein Kontinuum, das angibt, inwieweit die Sprache versucht, Fehler zu verhindern, die dadurch entstehen, dass eine Variable so verwendet wird, als wäre sie von einem bestimmten Typ, obwohl sie in Wirklichkeit von einem anderen Typ ist. Zum Beispiel sind sowohl C als auch Java statisch typisierte Sprachen, aber Java verwendet eine viel stärkere Typüberprüfung als C. Der folgende C-Code lässt sich problemlos kompilieren und ausführen, setzt aber zur Laufzeit einen zufälligen Wert in die Variable b, was höchstwahrscheinlich einen Fehler verursacht:
char *a = "123";
int b = (int)a;
Der entsprechende Java-Code führt zu einem Kompilierfehler, was im Allgemeinen vorzuziehen ist:
String a = "123"
int b = (int)a;
- See previous answers
- Weitere Antworten anzeigen