In dieser Serie werfen wir einen ersten Blick auf dynamisch typisierte (oder schwach typisierte) Sprachen und auf die Frage, wie das Fehlen eines starken Schreibens unsere Programmierung sowohl positiv als auch negativ beeinflussen kann.
Wie im ersten Beitrag erwähnt, richtet sich diese Serie speziell an Anfänger oder an diejenigen, die mit schwach typisierten Sprachen nicht viel Erfahrung haben. Das heißt, wenn Sie in stark typisierten und / oder schwach typisierten Sprachen programmiert haben und mit Typübernahme und den Fallstricken vertraut sind, die bei bestimmten Operationen auftreten können, ist diese Serie für Sie möglicherweise nicht besonders interessant.
Auf der anderen Seite, wenn Sie jemand sind, der gerade erst mit dem Schreiben von Code beginnt, oder wenn Sie in eine dynamisch typisierte Sprache aus einer anderen Sprache kommen, dann ist diese Serie speziell auf Sie ausgerichtet. Letztendlich besteht das Ziel darin, Typendruck zu definieren, zu zeigen, wie es funktioniert, und dann die Fallstricke zu untersuchen.
Laut Wikipedia wird Zwang wie folgt definiert:
In der Informatik sind Typkonvertierung, Typumwandlung und Zwang unterschiedliche Methoden, um eine Entität eines Datentyps implizit oder explizit in einen anderen zu ändern.
Oder Sie können dies auf eine einfachere Weise definieren, indem Sie einen Datentyp verwenden und ihn in einen anderen konvertieren. Die Sache ist, es gibt eine feine Linie zwischen Bekehrung und Zwang.
Als Faustregel neige ich dazu, daran zu denken Zwang wie ein Interpreter oder Compiler arbeitet, um zu bestimmen, welche Art von Vergleich gemacht wird Umwandlung ist eine explizite Änderung des Typs, die wir als Programmierer in unseren Code schreiben.
Schauen wir uns das genauer an.
Nehmen wir zum Beispiel an, dass Sie eine Zeichenfolge haben Beispiel
und sein Wert ist '5'
. In statisch typisierten Sprachen können Sie den Wert der Zeichenfolge umsetzen und in einen konvertieren int
durch verschiedene Methoden.
Angenommen, wir haben eine Ganze Zahl
Objekt mit einem parseInt
Methode. Die Methode akzeptiert einen String und gibt den Wert des Strings im Integer-Datentyp zurück. Der Code dafür könnte ungefähr so aussehen:
String Beispiel = '5'; Integer myInt = new Integer (); int intExample = myInt.parseInt (Beispiel); / * intExample hat jetzt den Wert 5 (nicht '5') * und Beispiel bezieht sich immer noch auf die Zeichenfolge '5' * /
Natürlich wird die Syntax von Sprache zu Sprache und dort variieren sind Andere Möglichkeiten, einen Wert auszugeben, geben Ihnen jedoch eine Idee, wie Sie einen Typ explizit in einen anderen konvertieren können.
Eine andere Möglichkeit, dies zu tun, ist die Verwendung eines Typ-Casting-Operators. Obwohl die Implementierung der Operation von Sprache zu Sprache unterschiedlich ist, werden die meisten Programmierer, die mit Sprachen im C-Stil gearbeitet haben, dies wahrscheinlich als etwas ähnliches erkennen:
int myInt = (int) Beispiel;
Im Allgemeinen erfolgt die Typumwandlung normalerweise, indem Sie den Typ, in den Sie die Variable in Klammern konvertieren möchten, vor die Variable selbst setzen. Im obigen Beispiel, myInt
wird jetzt enthalten 5
, eher, als '5'
und Beispiel
wird noch halten '5'
.
Wie bereits erwähnt, wird dies normalerweise im Zusammenhang mit kompilierten Sprachen durchgeführt
Es bleibt immer noch die Frage, wie sich der Typzwang von der Typumwandlung unterscheidet. Obwohl Zwang können Wenn Sie in kompilierten Sprachen vorkommen, ist es wahrscheinlicher, dass dies in interpretierten Sprachen oder in dynamisch typisierten Sprachen geschieht.
Darüber hinaus werden Sie mit hoher Wahrscheinlichkeit Typübertreibungen erleben, wenn Objekte verschiedener Typen verglichen werden oder wenn eine Operation oder Auswertung mit Variablen durchgeführt wird, die unterschiedliche Typen haben.
Nehmen wir als einfaches Beispiel an, dass wir in JavaScript zwei Variablen haben - sName
, iAge
- woher sName
bezieht sich auf den Namen einer Person und iAge
bezieht sich auf das Alter einer Person. Die Variablen verwenden zum Beispiel die Ungarische Notation, um einfach anzugeben, dass eine Zeichenfolge und eine Ganzzahl gespeichert wird.
Beachten Sie, dass dies ist nicht Ein Argument für oder gegen die ungarische Notation - das ist ein Thema für einen anderen Beitrag. Es wird hier verwendet, um deutlich zu machen, welche Art von Wert jede Variable gespeichert wird, sodass der Code leichter verfolgt werden kann.
Also gehen wir weiter und definieren unsere Variablen und ihre Werte:
var sName = 'John Doe'; var iAge = 32;
Nun können wir uns einige Beispiele ansehen, wie Typenzwang im Kontext einer interpretierten Sprache funktioniert. Zwei Beispiele dafür, wie Typ Zwang funktioniert, sind folgende:
Schauen wir uns jeweils ein Beispiel an:
/ ** * Beim Vergleich einer Zahl mit einem booleschen * wird der boolesche Wert * auf 'false' gesetzt. * / var result = iAge == wahr; / ** * Verkettungszeichenfolgen und -zahlen * zwingen die Anzahl zu einer Zeichenfolge. * * "John Doe ist 32 Jahre alt." * / var bio = sName + 'ist' + iAge + 'Jahre alt.';
Diese Beispiele sind relativ einfach. Der erste ist sinnvoll, da es keine Möglichkeit gibt, eine Zahl mit einem booleschen Wert zu vergleichen.
Beachten Sie im zweiten Beispiel, dass wir eine Zeichenfolge verwenden, diese mit einem anderen Satz von Zeichenfolgen verketten und auch die Nummer in der Verkettung verwenden. In diesem Fall wird die Zahl in eine Zeichenfolge umgewandelt und dann zusammen mit den übrigen Wörtern verkettet.
Dies ist eine Typübernahme: Wenn Sie eine Variable eines Typs verwenden und deren Wert in einen anderen Typ umwandeln, wenn Sie einen Vorgang oder eine Auswertung ausführen.
Die Sache ist, beide Beispiele sind sehr simpel. Schauen wir uns noch ein paar weitere an, um zu zeigen, wie Zwang, zumindest in JavaScript, bei Verkettungsoperationen funktioniert:
var eins, zwei resultat; // Eins und Zwei beziehen sich auf String-Werte von '1' und '2' one = '1'; zwei = '2'; // Ergebnis enthält die Zeichenfolge '12'; Ergebnis = Eins + Zwei; // zwei neu definieren, um gleich die Zahl '2' zu sein zwei = 2; // Verkettung eines Strings und einer Zahl führt zu einem String // Ergebnis enthält '12'; Ergebnis = Eins + Zwei; // Neubezeichnung als Zahl Eins = 1; // dann verketten (oder summieren) die beiden Werte // Ergebnis ist 3 Ergebnis = Eins + Zwei;
Es gibt zwei wichtige Dinge zu beachten:
+
Operator ist überlastet. Das heißt, wenn es mit Strings arbeitet, werden diese miteinander verkettet, aber wenn es mit Zahlen arbeitet, fügt es sie zusammen.Um das Beispiel noch einen Schritt weiter zu bringen, fügen wir eine weitere Variable und eine Gruppe von Operationen mit Priorität hinzu und untersuchen dann das Ergebnis:
var eins, zwei, Baum, Ergebnis; Eins = '1'; zwei = 2; drei = 3; // Ergebnis ist '123' Ergebnis = Eins + Zwei + Drei; // Ergebnis ist '15' Ergebnis = Eins + (Zwei + Drei);
Beachten Sie im zweiten Beispiel, zwei
und drei
sind hinzugefügt zusammen, weil sie beide Zahlen sind und das Ergebnis dann ist verkettet mit ein
weil es eine schnur ist.
Zuvor haben wir erwähnt, dass es einen Sonderfall für Zahlen und boolesche Werte gibt, zumindest in JavaScript. Und da dies die Sprache ist, die wir zur Untersuchung des Typus-Zwangs verwendet haben, und da dies eine Sprache ist, die in der modernen Webentwicklung häufig verwendet wird, werfen wir einen Blick darauf.
Beachten Sie bei JavaScript das 1
gilt als "wahrer" Wert und 0
ist besorgt, ein "falsey" -Wert zu sein. Diese Wörter werden als solche ausgewählt, da die Werte als Zahlen dienen können, aber auch ausgewertet werden wahr
oder falsch
wenn Sie einen Vergleich durchführen.
Schauen wir uns einige grundlegende Beispiele an:
var bTrue, bFalse, iZero, iOne, Ergebnis; bTrue = true; bFalse = falsch; iZero = 0; iOne = 1; // result enthält den booleschen Wert von false result = bTrue == iZero; // result enthält den booleschen Wert von true result = bTrue == iOne; // result enthält den booleschen Wert von false result = bFalse == iOne; // result enthält den booleschen Wert von true result = bFalse == iZero;
Beachten Sie, dass in den obigen Beispielen die Zahlenwerte sind gezwungen in ganzzahlige Werte aufgrund des Vergleichs, der durchgeführt wird.
Was passiert aber, wenn wir einen booleschen Wert von vergleichen? wahr
oder falsch
auf einen Stringwert von ein
oder Null
?
var bTrue, bFalse, sTrue, sFalse, Ergebnis; bTrue = true; bFalse = falsch; sTrue = '1'; sFalse = '0'; // Ergebnis ist wahr Ergebnis = bTrue == sTrue; // Ergebnis enthält falsches Ergebnis = bTrue == sFalse; // Ergebnis gilt als falsch; Ergebnis = bFalse == sTrue; // Ergebnis ist wahr Ergebnis = bFalse == sFalse;
An diesem Punkt können die Dinge sehr verwirrend werden, da wir einen String-Wert einer Zahl vergleichen 1
auf einen booleschen Wert von wahr
und wir erhalten ein boolesches Ergebnis, und das boolean ist wahr
.
Sinn ergeben? Wir werden uns das im nächsten Artikel etwas genauer ansehen, aber ich wollte zuerst die Grundlagen davon vorstellen.
Zu diesem Zeitpunkt können dynamisch typisierte Sprachen den Entwicklern Kopfschmerzen bereiten. Glücklicherweise gibt es Möglichkeiten, Code zu schreiben, der strenger ist als der, den wir oben haben und der genaue Ergebnisse liefert.
Zusätzlich enthalten einige dynamisch typisierte Sprachen auch Werte für nicht definiert
und für Null
. Diese Werte behalten auch die Werte "true" und "falsey" bei, die wiederum den Umgang mit Vergleichen beeinflussen.
Im letzten Artikel der Serie werden wir uns ansehen, wie Werte wie nicht definiert
und Null
Vergleichen Sie mit anderen Werten sowie untereinander und werfen Sie einen Blick auf einige Strategien, die wir implementieren können, die unseren Code widerstandsfähiger gegen falschen Typzwang machen und dadurch lesbarer machen.
Wenn dies Ihr erster Vorstoß in dynamisch getippte Sprachen oder in Form von Zwang ist und Sie Fragen, Kommentare oder Feedback haben, dann zögern Sie bitte nicht, einen Kommentar im nachstehenden Feed zu hinterlassen!