In JavaScript: The Good Parts von Douglas Crockford erwähnt er in seinem Vererbungskapitel:
Der andere Vorteil der klassischen Vererbung besteht darin, dass sie die Spezifikation eines Typensystems umfasst. Dies befreit den Programmierer größtenteils davon, explizite Casting-Operationen schreiben zu müssen, was sehr gut ist, da beim Casting die Sicherheitsvorteile eines Typsystems verloren gehen.
Was ist eigentlich Sicherheit? Schutz vor Datenkorruption, Hackern, Systemstörungen etc.?
Was sind die Sicherheitsvorteile eines Typsystems? Was unterscheidet ein Typensystem, das diese Sicherheitsvorteile bietet?
type-systems
type-safety
MistakesWereMade
quelle
quelle
Antworten:
Typsysteme verhindern Fehler
Typsysteme eliminieren illegale Programme. Betrachten Sie den folgenden Python-Code.
In Python schlägt dieses Programm fehl. es löst eine Ausnahme aus. In einer Sprache wie Java, C # oder Haskell ist dies nicht einmal ein legales Programm. Sie vermeiden diese Fehler vollständig, da sie in den Eingabeprogrammen einfach nicht möglich sind.
Ebenso schließt ein besseres Typsystem mehr Fehler aus. Wenn wir zu hochentwickelten Typsystemen aufsteigen, können wir Folgendes sagen:
Jetzt garantiert das Typensystem, dass es keine Division-durch-0-Fehler gibt.
Welche Art von Fehlern
Im Folgenden finden Sie eine kurze Liste der Fehler, die durch Systeme verhindert werden können
Schändliche Kätzchen(Ja, es war ein Witz)Und denken Sie daran, dies ist auch zur Kompilierungszeit . Sie müssen keine Tests mit 100% Codeabdeckung schreiben, um einfach nach Tippfehlern zu suchen. Der Compiler erledigt dies nur für Sie :)
Fallstudie: Typisierte Lambda-Rechnung
Okay, lassen Sie uns das einfachste aller Typsysteme untersuchen, einfach Lambda-Kalkül .
Grundsätzlich gibt es zwei Arten,
Und alle Ausdrücke sind entweder Variablen, Lambdas oder Anwendungen. Auf dieser Grundlage können wir beweisen, dass jedes gut typisierte Programm beendet wird. Es gibt nie eine Situation, in der das Programm für immer hängen bleibt oder sich wiederholt. Dies ist im normalen Lambda-Kalkül nicht nachweisbar, da dies nicht der Fall ist.
Denken Sie darüber nach, wir können Typsysteme verwenden, um zu gewährleisten, dass unser Programm nicht für immer wiederholt wird, ziemlich cool, oder?
Abstecher in dynamische Typen
Dynamische Typsysteme können identische Garantien bieten wie statische Typsysteme, jedoch nicht zur Kompilierungszeit, sondern zur Laufzeit. Tatsächlich können Sie seit der Laufzeit mehr Informationen anbieten. Sie verlieren jedoch einige Garantien, insbesondere in Bezug auf statische Eigenschaften wie die Terminierung.
Dynamische Typen schließen also bestimmte Programme nicht aus, sondern leiten fehlerhafte Programme an genau definierte Aktionen weiter, z. B. das Auslösen von Ausnahmen.
TLDR
Das Lange und Kurze ist, dass Typsysteme bestimmte Programme ausschließen. Viele der Programme sind in irgendeiner Weise fehlerhaft, daher vermeiden wir bei Typsystemen diese fehlerhaften Programme.
quelle
Die Realität selbst ist getippt. Sie können keine Längen zu Gewichten hinzufügen. Und während Sie Meter mit Füßen versehen können (beide sind Längeneinheiten), sollten Sie mindestens eine der beiden skalieren. Andernfalls kann Ihre Mars-Mission buchstäblich abstürzen.
In einem typsicheren System wäre das Hinzufügen von zwei Längen in verschiedenen Einheiten entweder ein Fehler gewesen oder hätte eine automatische Umwandlung verursacht.
quelle
Ein Typensystem hilft Ihnen, einfache Codierungsfehler zu vermeiden, oder lässt den Compiler diese Fehler für Sie abfangen.
Beispielsweise wird in JavaScript und Python das folgende Problem häufig nur zur Laufzeit festgestellt - und je nach Testqualität / Seltenheit schafft es die Bedingung möglicherweise tatsächlich in die Produktion:
Während eine stark typisierte Sprache Sie zwingt, explizit anzugeben, dass
a
es sich um ein Array handelt, können Sie keine Ganzzahl zuweisen. Auf diese Weise gibt es keine Chance,a
die Sie nicht haben werdenlength
- auch in den seltensten Fällen.quelle
Je früher im Softwareentwicklungszyklus ein Fehler auftritt, desto günstiger ist die Fehlerbehebung. Stellen Sie sich einen Fehler vor, der dazu führt, dass Ihr größter Kunde oder alle Ihre Kunden Daten verlieren. Ein solcher Fehler könnte das Ende Ihres Unternehmens bedeuten, wenn er erst dann abgefangen wird, wenn echte Kunden Daten verloren haben! Es ist deutlich günstiger, diesen Fehler zu finden und zu beheben, bevor er in die Produktion verlagert wird.
Selbst bei weniger kostspieligen Fehlern wird mehr Zeit und Energie aufgewendet, wenn Tester beteiligt sind, als wenn Programmierer sie finden und beheben können. Es ist billiger, wenn es nicht in die Quellcodeverwaltung eingecheckt wird, wo andere Programmierer Software entwickeln können, die darauf basiert. Die Typensicherheit verhindert, dass bestimmte Fehlerklassen überhaupt kompiliert werden, und beseitigt so fast die gesamten potenziellen Kosten dieser Fehler.
Aber das ist nicht die ganze Geschichte. Wie jeder, der in einer dynamischen Sprache programmiert, Ihnen mitteilt, ist es manchmal schön, wenn Ihr Programm nur kompiliert wird, damit Sie einen Teil davon ausprobieren können, ohne jedes Detail herauszufinden. Es gibt einen Kompromiss zwischen Sicherheit und Komfort. Komponententests können das Risiko der Verwendung einer dynamischen Sprache etwas verringern, aber das Schreiben und Beibehalten guter Komponententests ist mit höheren Kosten verbunden als die Verwendung einer typsicheren Sprache.
Wenn Sie experimentieren, wenn Ihr Code nur einmal verwendet wird (z. B. ein einmaliger Bericht) oder wenn Sie sich in einer Situation befinden, in der Sie ohnehin keinen Komponententest schreiben würden, ist eine dynamische Sprache wahrscheinlich perfekt für dich. Wenn Sie eine große Anwendung haben und ein Teil ändern möchten, ohne den Rest zu beschädigen, ist Typensicherheit ein Lebensretter. Die Arten von Fehlern und Sicherheitsmechanismen sind genau die Arten von Fehlern, die Menschen beim Refactoring häufig übersehen oder falsch verstehen.
quelle
Einführung
Die Typensicherheit kann entweder mit statisch typisierten (kompilierten, statischen Typprüfungen) und / oder Laufzeitsprachen (evaluierte, dynamische Typprüfungen) erreicht werden. Laut Wikipedia wird ein '... starkes Typsystem als eines beschrieben, bei dem es keine Möglichkeit für einen ungeprüften Laufzeitfehler gibt (ed Luca Cardelli). Mit anderen Worten, das Fehlen von ungeprüften Laufzeitfehlern wird als Sicherheit oder Typensicherheit bezeichnet ... “
Sicherheit - Statische Typprüfung
Typensicherheit ist seit jeher ein Synonym für statische Typisierung in Sprachen wie C, C ++ und Haskell, mit denen Typenkonflikte beim Kompilieren erkannt werden. Dies hat den Vorteil, dass potenziell undefinierte oder fehleranfällige Bedingungen bei der Ausführung des Programms vermieden werden. Dies kann von unschätzbarem Wert sein, wenn das Risiko besteht, dass Zeigertypen falsch zugeordnet werden, z. B. wenn eine Situation nicht erkannt wird, die zu katastrophalen Folgen führen kann. In diesem Sinne ist statisches Schreiben gleichbedeutend mit Speichersicherheit.
Die statische Eingabe ist nicht vollständig sicher, erhöht jedoch die Sicherheit . Selbst statisch typisierte Systeme können katastrophale Folgen haben. Viele Experten sind der Ansicht, dass statisch typisierte Systeme verwendet werden können, um robustere und weniger fehleranfällige (geschäftskritische) Systeme zu schreiben.
Statisch geschriebene Sprachen können dazu beitragen, das Risiko von Datenverlusten oder Genauigkeitsverlusten bei numerischen Arbeiten zu verringern, die durch falsches Anpassen oder Abschneiden von double-to-float oder falsches Anpassen von Integral- und Float-Typen auftreten können.
Die Verwendung statisch typisierter Sprachen bietet einen Vorteil hinsichtlich Effizienz und Ausführungsgeschwindigkeit. Die Laufzeit profitiert davon, dass die Typen während der Ausführung nicht ermittelt werden müssen.
Sicherheit - Laufzeitprüfung
Erlang ist beispielsweise eine typdeklarative, dynamisch typüberprüfte Sprache, die auf einer virtuellen Maschine ausgeführt wird. Erlang Code kann byteweise kompiliert werden. Erlang gilt als die vielleicht wichtigste geschäftskritische , fehlertolerante Sprache, und es wird berichtet, dass Erlang eine Zuverlässigkeit von neun Neunern (99,9999999% oder nicht mehr als 31,5 ms pro Jahr) aufweist.
Bestimmte Sprachen, wie z. B. Common Lisp, sind nicht statisch typisiert. Auf Wunsch können jedoch Typen deklariert werden, um die Geschwindigkeit und Effizienz zu verbessern. Es ist auch zu beachten, dass viele der am häufigsten verwendeten interpretierten Sprachen wie Python unterhalb der Evaluierungsschleife in statisch typisierten Sprachen wie C oder C ++ geschrieben sind. Sowohl Commom Lisp als auch Python gelten nach der obigen Definition als typsicher.
quelle
1 + "1"
eine Ausnahme ausgelöst, während in PHP (schwach typisiert) eine Ausnahme1 + "1"
erzeugt wird2
(Zeichenfolge"1"
wird automatisch in Ganzzahl konvertiert1
).Ich habe das Gefühl, dass Typsysteme eine so negative Sichtweise haben. Bei einem Typensystem geht es mehr um eine Garantie als um den Nachweis der Fehlerfreiheit. Letzteres ist eine Konsequenz des Typsystems. Ein Typensystem für eine Programmiersprache ist eine Möglichkeit, beim Kompilieren den Beweis zu erbringen, dass ein Programm einer bestimmten Spezifikation entspricht.
Die Art der Spezifikation, die man als Typ codieren kann, hängt von der Sprache oder direkter von der Stärke des Typensystems der Sprache ab.
Die grundlegendste Art der Spezifikation ist eine Garantie für das Ein- / Ausgabeverhalten von Funktionen und die Gültigkeit des Inneren eines Funktionskörpers. Betrachten Sie einen Funktionsheader
Ein gutes Typsystem stellt sicher, dass f nur auf Objekte angewendet wird, die bei der Auswertung ein Paar Int erzeugen, und garantiert, dass f immer eine Zeichenfolge erzeugt.
Einige Anweisungen in einer Sprache, wie If-Then-Blöcke, weisen kein Eingabe- / Ausgabeverhalten auf. hier garantiert das Typensystem, dass jede Deklaration oder Anweisung im Block gültig ist; Dies gilt für Operationen an Objekten der richtigen Art. Diese Garantien sind zusammensetzbar.
Dies gibt auch eine Art Speicher-Sicherheitsbedingung. Das Zitat, mit dem Sie es zu tun haben, handelt vom Casting. In einigen Fällen ist das Umwandeln in Ordnung, wie das Umwandeln eines 32-Bit-Int in ein 64-Bit-Int. Im Allgemeinen stürzt das Typsystem jedoch ab.
Erwägen
Aufgrund des Castings wird x in ein Int umgewandelt. Es macht jedoch den Zweck der Typenkontrolle zunichte.
Eine Sache, die ein anderes und besseres Typensystem hervorbringen könnte, ist das Verbieten von Würfen (A) x, wobei x vor dem Fall Typ B ist, es sei denn, B ist ein Subtyp (oder Subobjekt) von A. Die Ideen der Subtypentheorie wurden in der Sicherheit verwendet um die Möglichkeit von Integer-Überlauf- / Unterlaufangriffen auszuschließen.
Zusammenfassung
Ein Typensystem ist eine Methode, um zu beweisen, dass ein Programm einer bestimmten Spezifikation entspricht. Welche Vorteile ein Typensystem bieten kann, hängt von der Stärke des verwendeten Typensystems ab.
quelle
Ein Vorteil, der für ein Typensystem noch nicht erwähnt wurde, liegt in der Tatsache, dass viele Programme mehr gelesen als geschrieben werden, und in vielen Fällen kann ein Typensystem ermöglichen, dass viele Informationen auf eine Weise spezifiziert werden, die kurz und einfach ist von jemandem verdaut, der den Code liest. Während Parametertypen keine beschreibenden Kommentare ersetzen, finden es die meisten Leute schneller zu lesen: "int Distance;" oder
Distance As Int32
als zu lesen "Abstand muss eine ganze Zahl +/- 2147483647 sein"; Das Übergeben von Brüchen kann zu inkonsistenten Ergebnissen führen. "Darüber hinaus können Parametertypen dazu beitragen, die Lücke zwischen dem, was eine bestimmte Implementierung einer API tut, und dem, worauf sich Aufrufer verlassen dürfen, zu verringern. Beispielsweise, wenn eine bestimmte JavaScript-Implementierung einer API verwendet seine Parameter in einer Weise , die keine Strings in numerische Form zwingen würde, kann es unklar sein , ob Anrufer auf ein solches Verhalten verlassen dürfen, oder wenn andere Implementierungen der API könnte Störung Strings , wenn angegeben. eine Methode , deren Parameter, wie angegebenDouble
Would Stellen Sie klar, dass alle Zeichenfolgenwerte vom Aufrufer erzwungen werden müssen, bevor sie übergeben werden. Verwenden Sie eine Methode mit einer Überladung, die akzeptiert,Double
und eine andere, die akzeptiertString
würde etwas klarer machen, dass Anrufer, die Zeichenfolgen halten, diese als solche weitergeben dürfen.quelle
Alle anderen Antworten und mehr. Im Allgemeinen bedeutet "Typensicherheit" einfach, dass keines der Programme, die ein Compiler erfolgreich kompiliert, Typfehler enthält.
Was ist nun ein Tippfehler? Grundsätzlich können Sie jede unerwünschte Eigenschaft als Typfehler angeben, und einige Typsysteme können statisch sicherstellen, dass kein Programm einen solchen Fehler aufweist.
Mit "Eigenschaft" oben meine ich eine Art logischen Satz, der für Ihr Programm gilt, z. B. "Alle Indizes liegen innerhalb der Arraygrenzen". Andere Arten von Eigenschaften umfassen: "Alle referenzierten Zeiger sind gültig", "Dieses Programm führt keine E / A aus" oder "Dieses Programm führt E / A nur nach / dev / null aus" usw. Fast jede Art von Abhängig von der Aussagekraft Ihres Typsystems kann auf diese Weise die Eigenschaft angegeben und der Typ überprüft werden.
Abhängige Typsysteme gehören zu den allgemeinsten Typsystemen, über die Sie so ziemlich jede Eigenschaft erzwingen können, die Sie möchten. Dies ist jedoch nicht unbedingt einfach, da anspruchsvolle Eigenschaften der Unvollständigkeit von Gödel unterliegen .
quelle