Wenn ich scala's Predef
-Objekt anschaue, das automatisch importiert wird, habe ich folgendes Juwel
Dies hat dazu geführt, dass sich einige schmutzige Fehler in meinen Code eingeschlichen haben (verwendet _1
anstelle von _2
in Map[Char,Int]
). Ich verstehe es wirklich nicht, warum sollte ich implizit Char
in Int
konvertieren wollen. Die ganze Idee, den Typ Char
zu haben (was eine bloße Zahl ist) ist so, dass ich ihn nicht als Zahl verwenden werde (oder umgekehrt).
Ich benutze das Scala-Typ-System, um solche Fehler nicht zu haben!
Die einzige (schlechte) Entschuldigung, über die ich nachdenke, ist, mit Javas schrecklichem Verhalten kompatibel zu sein.
update: Der Hauptgrund, der durch die beiden bisher gegebenen Antworten gegeben wird, ist, dass die implizite Konvertierung durchgeführt wird, um geordnete Aktionen nach dem Char
-Typ zu unterstützen. So würde zum Beispiel 'c'+1
d
generieren. Wenn es das ist, was du willst, solltest du
und du kannst Charaktere nach deinen Wünschen hinzufügen und vergleichen. Die Tatsache, dass Char
die einzige 16-Bit-Zahl ist, bedeutet nur, dass wir einen neuen Word
(oder Short
) -Typ benötigen.
Nun, wenn Sie sich vorstellen, wie ein Char
dargestellt wird, dann ist Char
nur ein vorzeichenloses 16-Bit-Feld mit einem Bereich von (0 bis 2 ^ 16 - 1). Dies kann ohne Überlauf in Int
(32-Bit-Zeichen mit einem Bereich von -2 ^ 31 bis 2 ^ 31 - 1) passen.
Einige der Grundtypen von Scala sind in der Reihenfolge der Länge ihrer Darstellung in Bits:
Byte
(8) Char
(16) Int
(32) Long
(64) Alle sind signiert, außer für Char
und alle sind in einen Typ "unter" umwandelbar, da sie niemals über- / unterlaufen würden (außer für Byte
bis Char
, was nicht existiert). Sehen Sie sich all diese impliziten Konvertierungen im Predef .
Aus diesem Grund glaube ich, dass die impliziten Konvertierungen existieren - damit Ausdrücke wie das Folgende existieren können:
%Vor% Eine andere Erklärung ist die, die Sie angegeben haben (a Char
ist nur eine Zahl ...). Für mich macht es Sinn - die Menge aller Chars
ist in der Menge aller Int
s enthalten und daher meine eigenen Richtlinien für die Verwendung von implicits anwenden , sollte die Konvertierung implizit sein.
Ich verstehe Ihre Belästigung, weil ich Compiler gerne Fehler signalisiere, wie Sie sie gerade als Beispiel angeführt haben. Es wäre schön, wenn Scala eine Möglichkeit hätte, die implizite Konvertierung auszuschalten (oder implizite Conversions zu deaktivieren, da es wahrscheinlich sehr schaden würde, wenn sie alle ausgeschaltet würden!)
Die einzige Lösung, die ich für Ihr Problem sehe, ist die Verwendung von Map[RichChar, Int]
oder etwas Ähnliches - RichChar
wird implizit in ein Int
konvertiert, da implizite Konvertierungen nicht verkettet werden können. BEARBEITEN hat herausgefunden, dass es tatsächlich eine nein implizite Konvertierung von RichChar
nach Char
gibt.
BEARBEITEN : Wenn Sie sich die Scala API genauer ansehen, Char
hat eine überladene +
Methode, die ein Int
Argument benötigt. Gleiches gilt für Int
. Dies könnte damit zu tun haben, dass die zugrundeliegende JVM etwas Ähnliches tut.
Beachten Sie auch, dass das Beispiel, das ich Ihnen gegeben habe, nichts mit dem Hinzufügen von Int
s zu Char
s zu tun hat! Dies ist bereits von der API erlaubt. Der subtilere Punkt ist, dass wenn Sie ein Int
zu einem Char
hinzufügen, Sie ein Int
erhalten. Die implizite Konvertierung ist dazu da, das Ergebnis dieser Addition als Char
zu verwenden.
Beachten Sie auch die theoretischere Antwort, die ich gegeben habe - Char
ist eine Untermenge von Int
!
-- Flaviu Cipcigan
Es ist nur eine Implementierungswahl. An einem Punkt unterschieden sich viele Sprachen stark zwischen char
und int
, aber da sie immer Konvertierungsfunktionen haben mussten, blockierte sie nicht wirklich viel und es wurde nur ein großer Schmerz .
Niemand möchte wirklich zu den Tagen von chr(n)
und ord(c)
zurückkehren. Stellen Sie sich vor, was für ein Spaß UTF-8-Handling wäre.
Sobald C herauskam mit char
s war wirklich int
s, rockte es, und wir sind damit auch in viel stärker typisierten Sprachen geblieben.
Wenn Sie nun wirklich ein gekapseltes Char
wollen, das nicht automatisch konvertiert, hält Sie nichts davon ab, einen neuen Typ, zB ElazarChar
, für Ihren eigenen Code zu definieren. Ich vermute, dass du es hassen wirst.