Warum konvertiert Scala Char implizit in Int?

9

Wenn ich scala's Predef -Objekt anschaue, das automatisch importiert wird, habe ich folgendes Juwel

%Vor%

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

machen %Vor%

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.

    
Elazar Leibovich 26.09.2009, 18:26
quelle

2 Antworten

5

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.

%Vor%

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

    
Flaviu Cipcigan 26.09.2009, 20:58
quelle
0

Es mag nicht perfekt sein, aber bedenke die Alternative ...

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.

    
DigitalRoss 26.09.2009 20:58
quelle

Tags und Links