inkompatible Typen: int kann nicht in boolean konvertiert werden
Ich bin daran interessiert, warum C es zulässt und Java nicht. Aus diesem Grund interessiert mich das Typensystem der Sprache, insbesondere ihre Stärke.
Ihre Frage besteht aus zwei Teilen:
Warum konvertiert Java nicht int
nach boolean
?
Dies läuft darauf hinaus, dass Java so explizit wie möglich sein soll. Es ist sehr statisch, sehr "in deinem Gesicht" mit seinem Typensystem. Dinge, die automatisch in andere Sprachen geschrieben werden, sind in Java nicht so. Du musst auch schreiben int a=(int)0.5
. Die Konvertierung float
in int
würde Informationen verlieren. das gleiche wie konvertieren int
zu boolean
und wäre daher fehleranfällig. Außerdem hätten sie viele Kombinationen angeben müssen. Sicher, diese Dinge scheinen offensichtlich zu sein, aber sie wollten sich auf der Seite der Vorsicht irren.
Im Vergleich zu anderen Sprachen war Java in seiner Spezifikation äußerst genau, da der Bytecode nicht nur ein internes Implementierungsdetail war. Sie müssten alle Wechselwirkungen genau spezifizieren. Riesiges Unterfangen.
Warum if
akzeptiert nicht andere Typen als boolean
?
if
könnte durchaus definiert werden, um andere Typen als zuzulassen boolean
. Es könnte eine Definition haben, die besagt, dass Folgendes äquivalent ist:
true
int != 0
String
mit .length>0
- Jeder andere Objektverweis, der nicht
null
(und kein Boolean
with-Wert false
) ist.
- Oder sogar: jede andere Objektreferenz, die nicht existiert
null
und deren Methode Object.check_if
(von mir nur für diesen Anlass erfunden) zurückgibt true
.
Sie taten nicht; Es gab keine wirkliche Notwendigkeit, und sie wollten es so robust, statisch, transparent, einfach zu lesen usw. wie möglich haben. Keine impliziten Funktionen. Außerdem wäre die Implementierung ziemlich komplex, da ich sicher bin, dass jeder Wert auf alle möglichen Fälle getestet werden muss, sodass die Leistung möglicherweise auch einen kleinen Einfluss hat (Java war auf den Computern dieses Tages früher nur langsam; denken Sie daran) Bei den ersten Releases gab es keine JIT-Compiler, zumindest nicht auf den damals verwendeten Computern.
Tieferer Grund
Ein tieferer Grund könnte wohl die Tatsache sein, dass Java seine primitiven Typen hat, weshalb sein Typensystem zwischen Objekten und Primitiven hin und her gerissen ist. Wenn sie diese vermieden hätten, wäre es vielleicht anders gekommen. Mit den im vorherigen Abschnitt angegebenen Regeln müssten sie die Wahrhaftigkeit jedes einzelnen Primitivs explizit definieren (da die Primitive keine Superklasse teilen und es null
für Primitive keine genaue Definition gibt ). Dies würde sich schnell in einen Albtraum verwandeln.
Ausblick
Nun, und am Ende ist es vielleicht nur eine Präferenz der Sprachdesigner. Jede Sprache scheint ihren eigenen Weg dorthin zu finden ...
Zum Beispiel hat Ruby keine primitiven Typen. Alles, buchstäblich alles, ist ein Objekt. Sie haben es sehr leicht, dafür zu sorgen, dass jedes Objekt eine bestimmte Methode hat.
Ruby sucht nach Wahrhaftigkeit für alle Arten von Objekten, die Sie darauf werfen können. Interessanterweise hat es immer noch keinen boolean
Typ (weil es keine Primitive hat) und es hat auch keine Boolean
Klasse. Wenn Sie fragen, mit welcher Klasse der Wert true
(handlich verfügbar true.class
) ist, erhalten Sie TrueClass
. Diese Klasse hat tatsächlich Methoden, nämlich die 4 Operatoren für boolean ( | & ^ ==
). Hier if
hält seinen Wert Falsey , wenn und nur wenn es entweder false
oder nil
(die null
von Ruby). Alles andere ist wahr. Also, 0
oder ""
sind beide wahr.
Es wäre für sie trivial gewesen, eine Methode Object#truthy?
zu entwickeln, die für jede Klasse implementiert werden kann und eine individuelle Wahrhaftigkeit zurückgibt. Beispielsweise String#truthy?
könnte implementiert worden sein, um für nicht leere Zeichenfolgen oder so weiter wahr zu sein. Sie taten es nicht, obwohl Ruby in den meisten Abteilungen das Gegenteil von Java ist (dynamisches Duck-Typing mit Mixin, Wiedereröffnung von Klassen und so weiter).
Was für einen Perl-Programmierer, der es gewohnt $value <> 0 || length($value)>0 || defined($value)
ist, die Wahrheit zu sein , vielleicht überraschend ist . Und so weiter.
Geben Sie SQL mit der Konvention ein, dass null
ein Ausdruck in jedem Ausdruck automatisch falsch ist, egal was passiert. Also (null==null) = false
. In Ruby (nil==nil) = true
. Glückliche Zeiten.