Diese Frage wurde hier gestellt , erhielt jedoch schlechte Antworten und hat das Problem nicht geklärt. Ich glaube, es rechtfertigt es, es noch einmal zu fragen.
Ich verstehe, dass Sie Enten entweder mit dynamisch oder mit statisch typisierten Sprachen tippen können (Beispiele dafür sind jedoch selten, wie z. B. die Vorlagen von C ++).
Ich bin mir jedoch nicht sicher, ob es eine dynamisch getippte Sprache ohne Ententipp gibt.
Ententypisierung bedeutet, dass der Typ eines Objekts auf den Operationen und Attributen basiert, die es zu einem bestimmten Zeitpunkt hat. Gibt es eine Möglichkeit, dynamisches Tippen durchzuführen, ohne zwangsläufig das Enten-Tippen zu unterstützen?
Schauen wir uns zum Beispiel diesen Python-Code an:
def func(some_object)
some_object.doSomething()
something = Toaster()
func(something)
In dynamisch typisierten Sprachen ist der Typ eines Objekts nur zur Laufzeit bekannt. Wenn Sie also versuchen, eine Operation darauf auszuführen (z. B. some_object.doSomething()
), hat die Laufzeit nur eine Wahl : Sie muss überprüfen, ob die Art der some_object
Stützen doSomething()
genau die Ententypisierung ist oder nicht .
Ist es also möglich, dynamisch typisierte Sprachen zu haben, ohne Enten zu tippen? Bitte erkläre.
quelle
1 + "1"
. In Pythons Fall fehlt die Disziplin der Überprüfung so gut wie und es liegt an der Implementierung des Benutzercodes, die Typen zu überprüfen, ob der Benutzer (im Gegensatz zur Python-Laufzeit) dies nützlich findet. Beachten Sie auch, dass die Typisierung von Enten im Vergleich zur Typisierung von Nicht-Enten der nominellen vs. strukturellen Typisierung entspricht (siehe Wikipedia).Antworten:
Um sicherzustellen, dass wir über die gleichen Dinge sprechen, würde ich zunächst mit einigen Definitionen beginnen.
Statische Typisierung bedeutet, dass Typfehler zur Kompilierungszeit gemeldet werden, während dynamische Typisierung bedeutet, dass Typfehler zur Laufzeit gemeldet werden.
Ententypisierung bedeutet, dass ein Teil des Codes erfordert, dass ein Objekt die verwendeten Operationen unterstützt und nicht mehr.
Die strukturelle Typisierung erfordert, dass ein Objekt einen bestimmten Satz von Operationen unterstützt (auch wenn einige von ihnen möglicherweise nicht verwendet werden).
Für die nominelle Typisierung muss das Objekt genau vom angegebenen Typ oder ein Untertyp dieses Typs sein.
Wie Sie sehen können, ist die strukturelle Typisierung strenger als die Ententypisierung, und die nominelle Typisierung ist strenger als die strukturelle.
Jetzt werde ich über die TypeScript-Sprache sprechen , da sie die meisten dieser Optionen gut veranschaulicht.
Betrachten Sie das folgende TypeScript-Programm:
Da das übergebene Objekt
greet
nicht über dieAge
Eigenschaft verfügt, verursacht dies einen Fehler bei der Kompilierung, der zeigt, dass TypeScript statische strukturelle Typisierung verwendet .Trotz des Fehlers wird der obige Code tatsächlich mit dem folgenden JavaScript kompiliert, das einwandfrei funktioniert:
Dies zeigt, dass TypeScript auch die dynamische Ententypisierung verwendet .
Wenn der Code stattdessen wie folgt kompiliert wurde:
Dies wäre dann ein Beispiel für eine dynamische strukturelle Typisierung , da überprüft wird, ob das Objekt die erforderlichen Eigenschaften der erforderlichen Typen aufweist, auch wenn die Funktion selbst diese nicht benötigt.
Wenn es kompiliert wurde zu:
Dies wäre ein Beispiel für eine dynamische nominelle Typisierung , da der Name des Objekttyps und nicht dessen Struktur überprüft wird.
Dies alles zeigt, dass eine dynamische Typisierung ohne Ente möglich ist (sowohl strukturell als auch nominal). Dieser Ansatz wird jedoch nicht sehr häufig verwendet, da er hauptsächlich die Nachteile der Nicht-Enten-Typisierung (Sie müssen Typen explizit angeben; weniger flexibel) und der dynamischen Typisierung (Typfehler werden nur zur Laufzeit und nur im tatsächlich ausgeführten Code angezeigt) kombiniert ).
Wenn Sie Typanmerkungen hinzufügen möchten, um die Eingabe ohne Enten zu ermöglichen, können Sie die Typen auch zur Kompilierungszeit überprüfen.
quelle
[3,4]
zu einem gewissen Verfahren einer Sammlung Halte[1,2]
Ausbeuten[1,2,3,4]
und vorbei[3,4]
an einige ein Verfahren zur Herstellung einiger Sammlung Halte[1,2]
würde[4,6]
, sollten die Methoden den gleichen Namen haben? Den erstenSequence$Appendable$Add
und den zweitenNumericVector$Add
Sequence
NumericVector
tsc
ist eine Schnittstelle hinein. Wenn Sie die Bibliothek verwenden, wird ein Ereignis ausgelöst. Wenn nichts zuhört, erhalten Sie standardmäßig ein Skript. Wenn Sie zuhören und eine Ausnahme auslösen, können Sie verhindern, dass das Skript generiert wird. Ändert das das Typsystem von TypeScript? Natürlich nicht.Anscheinend (nach dem, was ich gelesen habe) hat die Eingabe von Enten nur in einem objektorientierten Kontext eine Bedeutung, wenn Funktionen als Methoden an Objekte angehängt werden. Wenn Sie dann schreiben
duck.quacks(3)
, funktioniert dies, wenn der aktuelle Wert vonduck
die Methode hatquacks
.Die dynamische Typisierung ist nicht unbedingt mit Methoden an eine OO-Ansicht gebunden.
Sie können den Typ
real
mit dem zugeordneten Operator oder der zugeordneten Funktion+: real*real->real
und den Typrational
mit dem zugeordneten Operator definieren+: rational*rational->rational
. Wenn Sie danna+b
in einem dynamisch überprüften Zeitsystem beide Variablen schreibena
undb
möglicherweise einen+
Operator haben, wird jedoch ein Laufzeitfehler angezeigt .Dynamische Typisierungsprüfungen auf kategoriale Konsistenz von Werten, möglicherweise mehrere davon.
Duck Typing überprüft die Verhaltenskonsistenz des Codes mit einem Objekt (soweit ich es verstehe).
In gewisser Weise ist die Ententypisierung eine Form des Laufzeitpolymorphismus, mit der Ausnahme, dass sie nur für Zugriffsmethoden eines einzelnen Objekts gilt.
Man könnte jedoch möglicherweise eine allgemeinere Form des Laufzeitpolymorphismus definieren, bei der der auszuführende Operator
+
auf der Grundlage aller Argumente bestimmt wird. Damit eine Ente und ein Huhn zusammen tanzen können, wenn sie eine gemeinsame Tanzfunktion haben. Sie könnten mehrere haben, damit Enten auch mit Gänsen mit einer anderen Funktion tanzen können. Das scheint aber etwas kompliziert. Soweit ich mich erinnere, war mit den generischen Funktionen der Sprache EL1 , einem sehr alten Vorläufer objektorientierter Sprachen, möglicherweise etwas Ähnliches (mit wahrscheinlich mehr Struktur) möglich .quelle
Eine analoge Antwort:
Können Sie ein Cabrio kaufen und niemals das Verdeck ablegen? Sicher. Dies ist wahrscheinlich nicht der beste Weg, um Ihre Ressourcen auszugeben, da Sie für einige Funktionen (z. B. Cabrioverdeck, zusätzliche strukturelle Versteifung aufgrund fehlenden Daches als strukturelles Element) zusätzlich bezahlt werden und schlechtere Ergebnisse erzielen (z. B. zusätzliche Straßengeräusche, möglicherweise weniger) Crash-Sicherheit, kleinere Ablagefächer) als Folge der Investition in diese Funktion, die Sie nicht nutzen werden. Aber es ist technisch machbar.
Das Gleiche gilt für dynamische Sprachen und das Tippen von Enten. Sie haben die höhere Effizienz und die Sicherheitsgarantie für statische Sprachen zur Kompilierungszeit aufgegeben. Für was? Im Allgemeinen zur Vereinfachung der Ententypisierung. Variablen und Sammlungen können alles enthalten, und Sie müssen nicht viel im Voraus angeben, was genau. Gemischte Sammlungen wie
[ 12, "gumbo", 12.4, 4+4j ]
(eine Ganzzahl, eine Zeichenfolge, ein Gleitkommawert und ein komplexer Wert) sind trivial, und Sie haben nicht die konstante Typumwandlung, die Sie beispielsweise in Java-Code sehen.In einer dynamischen Sprache wie Python können Objekte erstellt werden, die nicht vom Typ Ente sind:
Wie Sie vielleicht bemerken, werden die Typen nicht wirklich überprüft, und jede der Methoden wird mit einer integrierten Struktur vom Typ Ente (
list
) implementiert . Nachdem Sie den Preis für Dynamik bezahlt haben, können Sie auch das Verdeck ablegen und die daraus resultierende Einfachheit erhalten:quelle
Hungarian
Klasse nicht vom Typ Ente? Wie Sie bereits betont haben, erfolgt keine Überprüfung der Typen.NotHungarian
Fall ist. Die Eingabe von Enten hängt nicht nur davon ab, dass der Typ nicht überprüft wird, sondern auch, dass derselbe Aufruf- / Methoden- / Nachrichtenname (add
) verwendet wird. (NotHungarian
Verwendet auch einen Methodennamenadd
, der mit anderen Python-Objekten üblich ist, wie z. B.set
"Quacksalber" wie diese anderen Objekte / Klassen.)eval
unmöglich machen. Die Motivation war nie, Typen loszuwerden, und einige dynamische Sprachen haben „allmähliches Tippen“. MJD hat eine schöne Präsentation über statische und dynamische Typisierung.