623 Stimmen

Was ist der Unterschied zwischen einer stark typisierten Sprache und einer statisch typisierten Sprache?

Bedeutet das eine auch das andere?

763voto

Norman Ramsey Punkte 193087

Was ist der Unterschied zwischen einer stark typisierten Sprache und einer statisch typisierten Sprache?

Eine statisch typisierte Sprache hat ein Typsystem, das zur Kompilierzeit von der Implementierung (einem Compiler oder Interpreter) überprüft wird. Die Typprüfung lehnt einige Programme ab, und Programme, die die Prüfung bestehen, sind in der Regel mit einigen Garantien verbunden; so garantiert der Compiler beispielsweise, dass keine ganzzahligen arithmetischen Anweisungen für Gleitkommazahlen verwendet werden.

Es besteht kein wirkliches Einvernehmen darüber, was "stark typisiert" bedeutet, obwohl die am weitesten verbreitete Definition in der Fachliteratur lautet, dass es dem Programmierer in einer "stark typisierten" Sprache nicht möglich ist, die durch das Typsystem auferlegten Einschränkungen zu umgehen. Dieser Begriff wird fast immer verwendet, um statisch typisierte Sprachen zu beschreiben.

Statisch vs. dynamisch

Das Gegenteil von statisch typisiert ist "dynamisch typisiert", was bedeutet, dass

  1. Die zur Laufzeit verwendeten Werte werden in Typen eingeteilt.
  2. Die Verwendung solcher Werte unterliegt Einschränkungen.
  3. Wenn diese Einschränkungen verletzt werden, wird die Verletzung als (dynamischer) Typfehler gemeldet.

Zum Beispiel, Lua Lua, eine dynamisch typisierte Sprache, hat unter anderem einen String-Typ, einen Zahlentyp und einen booleschen Typ. In Lua gehört jeder Wert zu genau einem Typ, aber dies ist nicht für alle dynamisch typisierten Sprachen erforderlich. In Lua ist es zulässig, zwei Strings zu verketten, aber es ist nicht zulässig, einen String und einen Boolean zu verketten.

Stark gegen schwach

Das Gegenteil von "stark typisiert" ist "schwach typisiert", was bedeutet, dass man das Typsystem umgehen kann. C ist notorisch schwach typisiert, weil jeder Zeigertyp durch einfaches Casting in jeden anderen Zeigertyp konvertierbar ist. Pascal sollte eigentlich stark typisiert sein, aber ein Versehen im Design (unmarkierte Variantendatensätze) führte ein Schlupfloch in das Typsystem ein, so dass es technisch gesehen schwach typisiert ist. Beispiele für wirklich stark typisierte Sprachen sind CLU, Standard ML und Haskell. Standard ML wurde mehrfach überarbeitet, um Schlupflöcher im Typsystem zu beseitigen, die entdeckt wurden, nachdem die Sprache weit verbreitet war.

Was ist hier wirklich los?

Insgesamt erweist es sich als nicht sehr nützlich, von "stark" und "schwach" zu sprechen. Ob ein Typsystem eine Lücke hat, ist weniger wichtig als die genaue Anzahl und Art der Lücken, wie wahrscheinlich es ist, dass sie in der Praxis auftreten, und welche Folgen die Ausnutzung einer Lücke hat. In der Praxis, Am besten ist es, die Begriffe "stark" und "schwach" gänzlich zu vermeiden. denn

  • Amateure verwechseln sie oft mit "statisch" und "dynamisch".

  • Offenbar wird der Begriff "schwache Typisierung" von einigen Personen verwendet, um über die relative Prävalenz oder Abwesenheit von impliziten Konvertierungen zu sprechen.

  • Die Fachleute sind sich nicht einig, was die Begriffe genau bedeuten.

  • Insgesamt ist es unwahrscheinlich, dass Sie Ihr Publikum informieren oder aufklären.

Die traurige Wahrheit ist, dass, wenn es um Schriftsysteme geht, Die Begriffe "stark" und "schwach" haben keine allgemein anerkannte technische Bedeutung. Wenn Sie über die relative Stärke von Typsystemen diskutieren wollen, ist es besser, genau zu erörtern, welche Garantien gegeben sind und welche nicht. Eine gute Frage, die man stellen kann, ist zum Beispiel folgende: "Ist garantiert, dass jeder Wert eines bestimmten Typs (oder einer Klasse) durch den Aufruf eines der Konstruktoren dieses Typs erzeugt worden ist?" In C lautet die Antwort nein. In CLU, F# und Haskell lautet sie Ja. Bei C++ bin ich mir nicht sicher - ich würde es gerne wissen.

Im Gegensatz dazu, statische Typisierung bedeutet, dass die Programme vor der Ausführung geprüft und ein Programm kann abgelehnt werden, bevor es startet. Dynamische Schreibweise bedeutet, dass die Arten von Werte geprüft werden während Ausführung, und eine schlecht getippte Operation kann dazu führen, dass das Programm anhält oder anderweitig zur Laufzeit einen Fehler meldet. Ein Hauptgrund für die statische Typisierung besteht darin, Programme auszuschließen, die solche "dynamischen Typfehler" aufweisen könnten.

Schließt das eine das andere ein?

Pedantisch ausgedrückt, nein, denn das Wort "stark" bedeutet eigentlich nichts. Aber in der Praxis tun die Menschen fast immer eines von zwei Dingen:

  • Sie verwenden (fälschlicherweise) "stark" und "schwach" im Sinne von "statisch" und "dynamisch", so dass sie (fälschlicherweise) "stark typisiert" und "statisch typisiert" austauschbar verwenden.

  • Sie verwenden "stark" und "schwach", um Eigenschaften statischer Typsysteme zu vergleichen. Es ist sehr selten, dass jemand von einem "starken" oder "schwachen" dynamischen Typsystem spricht. Mit Ausnahme von FORTH, das nicht wirklich ein Typsystem hat, fällt mir keine dynamisch typisierte Sprache ein, bei der das Typsystem unterlaufen werden kann. Diese Überprüfungen sind quasi per Definition in die Ausführungsmaschine eingebaut, und jede Operation wird vor ihrer Ausführung auf ihre Korrektheit überprüft.

Wie auch immer, wenn jemand eine Sprache als "stark typisiert" bezeichnet, ist es sehr wahrscheinlich, dass er eine statisch typisierte Sprache meint.

308voto

cletus Punkte 596503

Dies wird oft missverstanden, daher möchte ich es aufklären.

Statische/Dynamische Typisierung

Statische Typisierung ist der Ort, an dem der Typ an den variabel . Die Typen werden bei der Kompilierung geprüft.

Dynamische Schreibweise ist der Ort, an dem der Typ an den Wert . Die Typen werden zur Laufzeit geprüft.

So zum Beispiel in Java:

String s = "abcd";

s wird "für immer" ein String . Während seiner Lebensdauer kann er auf verschiedene String s (da s ist eine Referenz in Java). Sie kann eine null Wert, der sich aber nie auf einen Integer ou un List . Das ist statische Typisierung.

In PHP:

$s = "abcd";          // $s is a string
$s = 123;             // $s is now an integer
$s = array(1, 2, 3);  // $s is now an array
$s = new DOMDocument; // $s is an instance of the DOMDocument class

Das ist dynamisches Tippen.

Starke/schwache Typisierung

(Edit alert!)

Starkes Tippen ist eine Phrase, über deren Bedeutung keine breite Übereinstimmung besteht. Die meisten Programmierer, die diesen Begriff verwenden, um etwas anderes als statische Typisierung zu meinen, verwenden ihn, um zu implizieren, dass es eine Typdisziplin gibt, die durch den Compiler erzwungen wird. CLU hat zum Beispiel ein starkes Typsystem, das es dem Client-Code nicht erlaubt, einen Wert eines abstrakten Typs zu erzeugen, es sei denn, er verwendet die vom Typ bereitgestellten Konstruktoren. C hat ein ziemlich starkes Typsystem, das aber bis zu einem gewissen Grad "unterlaufen" werden kann, da ein Programm immer einen Wert eines Zeigertyps in einen Wert eines anderen Zeigertyps umwandeln kann. So kann man in C zum Beispiel einen Wert, der von malloc() und warf ihn fröhlich zu FILE* und der Compiler wird nicht versuchen, Sie zu stoppen - oder Sie sogar warnen, dass Sie etwas Fragwürdiges tun.

(In der ursprünglichen Antwort stand etwas von einem Wert, der "zur Laufzeit seinen Typ nicht ändert". Ich habe viele Sprachentwickler und Compilerautoren kennengelernt und keinen, der davon sprach, dass Werte zur Laufzeit ihren Typ ändern, außer vielleicht in der sehr fortgeschrittenen Forschung zu Typsystemen, wo dies als "starkes Aktualisierungsproblem" bekannt ist).

Schwache Typisierung impliziert, dass der Compiler keine Typisierungsvorschrift durchsetzt, oder dass die Durchsetzung leicht unterlaufen werden kann.

Das Original dieser Antwort verwechselte schwache Typisierung mit implizite Umrechnung (manchmal auch "implizite Promotion" genannt). Zum Beispiel, in Java:

String s = "abc" + 123; // "abc123";

Dieser Code ist ein Beispiel für implizite Werbung: 123 wird implizit in eine Zeichenkette umgewandelt, bevor sie mit "abc" . Man kann argumentieren, dass der Java-Compiler diesen Code umschreibt als:

String s = "abc" + new Integer(123).toString();

Betrachten Sie ein klassisches PHP "beginnt mit" Problem:

if (strpos('abcdef', 'abc') == false) {
  // not found
}

Der Fehler liegt hier darin, dass strpos() gibt den Index der Übereinstimmung zurück, also 0. 0 wird in den booleschen Wert gezwungen false und somit ist die Bedingung tatsächlich erfüllt. Die Lösung ist die Verwendung von === anstelle von == um eine implizite Konvertierung zu vermeiden.

Dieses Beispiel zeigt, wie eine Kombination aus impliziter Konvertierung und dynamischer Typisierung Programmierer in die Irre führen kann.

Vergleichen Sie das mit Ruby:

val = "abc" + 123

was ein Laufzeitfehler ist, weil in Ruby die Objekt 123 ist no implizit umgewandelt werden, nur weil sie zufällig an eine + Methode. In Ruby muss der Programmierer die Umwandlung explizit machen:

val = "abc" + 123.to_s

Ein Vergleich zwischen PHP und Ruby ist hier eine gute Illustration. Beide sind dynamisch typisierte Sprachen, aber PHP hat viele implizite Konvertierungen und Ruby (vielleicht überraschend, wenn Sie damit nicht vertraut sind) nicht.

Statisch/Dynamisch vs. stark/schwach

Der Punkt ist, dass die statische/dynamische Achse unabhängig von der starken/schwachen Achse ist. Die Leute verwechseln sie wahrscheinlich zum Teil deshalb, weil der Unterschied zwischen starker und schwacher Typisierung nicht nur weniger klar definiert ist, sondern es auch keinen wirklichen Konsens darüber gibt, was genau mit stark und schwach gemeint ist. Aus diesem Grund ist die starke/schwache Typisierung eher eine Grauzone als ein Schwarz oder Weiß.

Um Ihre Frage zu beantworten: Es gibt noch eine andere Möglichkeit, das Ganze zu betrachten. meist Richtig ist, dass statische Typisierung Kompilierzeit-Typsicherheit und starke Typisierung Laufzeit-Typsicherheit bedeutet.

Der Grund dafür ist, dass Variablen in einer statisch typisierten Sprache einen Typ haben, der deklariert werden muss und zur Kompilierzeit überprüft werden kann. Eine stark typisierte Sprache hat Werte, die zur Laufzeit einen Typ haben, und es ist für den Programmierer schwierig, das Typsystem ohne eine dynamische Prüfung zu unterlaufen.

Aber es ist wichtig zu verstehen, dass eine Sprache statisch/stark, statisch/schwach, dynamisch/stark oder dynamisch/schwach sein kann.

61voto

Daren Thomas Punkte 64742

Beide sind Pole auf zwei verschiedenen Achsen:

  • stark typisiert vs. schwach typisiert
  • statisch typisiert vs. dynamisch typisiert

Stark typisiert bedeutet, dass eine Variable nicht automatisch von einem Typ in einen anderen umgewandelt wird. Schwach typisiert ist das Gegenteil: Perl kann eine Zeichenkette wie "123" in einem numerischen Kontext durch automatische Konvertierung in den Wert int 123 . Eine stark typisierte Sprache wie Python wird dies nicht tun.

Statisch typisiert bedeutet, dass der Compiler den Typ jeder Variablen zur Kompilierzeit herausfindet. Dynamisch typisierte Sprachen ermitteln die Typen der Variablen erst zur Laufzeit.

42voto

Svetlozar Angelov Punkte 20324

Stark typisiert bedeutet, dass es Beschränkungen für Konvertierungen zwischen Typen gibt.

Statisch typisiert bedeutet, dass die Typen nicht dynamisch sind - Sie können den Typ einer Variablen nicht mehr ändern, sobald sie erstellt wurde.

17voto

Balkrishna Punkte 2613

Die Antwort wurde bereits oben gegeben. Ich versuche, zwischen starkem und schwachem sowie statischem und dynamischem Konzept zu unterscheiden.

Was ist Strongly typed VS Weakly typed?

Stark getippt: Wird nicht automatisch von einem Typ in einen anderen umgewandelt

In Go oder Python wie stark typisierten Sprachen wird "2" + 8 einen Typfehler auslösen, da sie keine "Typenzwang" zulassen.

Schwach (lose) getippt: Wird automatisch von einem Typ in einen anderen umgewandelt: Schwach typisierte Sprachen wie JavaScript oder Perl geben keinen Fehler aus und in diesem Fall ergibt JavaScript '28' und Perl 10.

Perl Beispiel:

my $a = "2" + 8;
print $a,"\n";

Speichern Sie es als main.pl und führen Sie es aus perl main.pl und Sie erhalten die Ausgabe 10.

Was ist ein statischer und ein dynamischer Typ?

In der Programmierung definieren Programmierer die statische Typisierung und die dynamische Typisierung in Bezug auf den Punkt, an dem die Variablentypen überprüft werden. Statisch typisierte Sprachen sind solche, in denen die Typenprüfung zur Kompilierzeit erfolgt, während dynamisch typisierte Sprachen solche sind, in denen die Typenprüfung zur Laufzeit erfolgt.

  • Statisch: Vor der Laufzeit geprüfte Typen
  • Dynamisch: Typen werden während der Ausführung überprüft.

Was bedeutet das?

In Go wird die Typisierung vor der Laufzeit geprüft (statische Prüfung). Dies bedeutet, dass es nicht nur übersetzt und Typ-Prüfungen Code es ausgeführt wird, aber es wird durch alle den Code und Typ-Fehler würde geworfen werden, bevor der Code sogar ausgeführt wird. Zum Beispiel,

package main

import "fmt"

func foo(a int) {
    if (a > 0) {
        fmt.Println("I am feeling lucky (maybe).")
    } else {
        fmt.Println("2" + 8)
    }
}

func main() {
    foo(2)
}

Speichern Sie diese Datei in main.go und führen Sie sie aus. Sie erhalten dann die Meldung, dass die Kompilierung fehlgeschlagen ist.

go run main.go
# command-line-arguments
./main.go:9:25: cannot convert "2" (type untyped string) to type int
./main.go:9:25: invalid operation: "2" + 8 (mismatched types string and int)

Dieser Fall gilt jedoch nicht für Python. Zum Beispiel wird der folgende Codeblock beim ersten foo(2)-Aufruf ausgeführt und schlägt beim zweiten foo(0)-Aufruf fehl. Das liegt daran, dass Python dynamisch typisiert ist, es übersetzt und prüft nur den Code, auf dem es ausgeführt wird. Der else-Block wird nie für foo(2) ausgeführt, also wird "2" + 8 nicht einmal betrachtet und für den foo(0)-Aufruf wird versucht, diesen Block auszuführen, was nicht gelingt.

def foo(a):
    if a > 0:
        print 'I am feeling lucky.'
    else:
        print "2" + 8
foo(2)
foo(0)

Sie werden folgende Ausgabe sehen

python main.py
I am feeling lucky.
Traceback (most recent call last):
  File "pyth.py", line 7, in <module>
    foo(0)
  File "pyth.py", line 5, in foo
    print "2" + 8
TypeError: cannot concatenate 'str' and 'int' objects

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X