incompatible types: int cannot be converted to boolean
I'm interested in why C does allow it and java not. Therefore, I'm interested in the language's type system, specifically its strongness.
Ci sono due parti alla tua domanda:
Perché Java non converte int
in boolean
?
Questo si riduce a Java per essere il più esplicito possibile. È molto statico, molto "in faccia" con il suo sistema di tipo. Le cose che vengono digitate automaticamente in altre lingue non sono così, in Java. Devi scrivere int a=(int)0.5
pure. Convertire float
in int
perderebbe informazioni; come convertire int
in boolean
e sarebbe quindi soggetto a errori. Inoltre, avrebbero dovuto specificare molte combinazioni. Certo, queste cose sembrano essere ovvie, ma intendevano sbagliare sul lato della cautela.
Oh, e rispetto ad altri linguaggi, Java era estremamente esatto nelle sue specifiche, in quanto il bytecode non era solo un dettaglio di implementazione interno. Dovrebbero specificare tutte le interazioni, precisamente. Enorme impresa.
Perché if
non accetta altri tipi di boolean
?
if
potrebbe perfettamente essere definito in modo da consentire altri tipi oltre boolean
. Potrebbe avere una definizione che dice che i seguenti sono equivalenti:
-
true
-
int != 0
-
String
con .length>0
- Qualsiasi altro riferimento a un oggetto che non è
null
(e non a Boolean
con valore false
).
- O anche: qualsiasi altro riferimento all'oggetto che non è
null
e il cui metodo Object.check_if
(inventato da me solo per questa occasione) restituisce true
.
Non l'hanno fatto; non ce n'era bisogno reale e volevano che fosse robusto, statico, trasparente, facile da leggere ecc. possibile. Nessuna caratteristica implicita. Inoltre, l'implementazione sarebbe piuttosto complessa, ne sono sicuro, dovendo testare ogni valore per tutti i possibili casi, quindi anche le prestazioni potrebbero aver giocato un piccolo fattore (Java era solito essere sloooow sui computer di quel giorno; non c'erano compilatori JIT con le prime versioni, almeno non sui computer che usavo allora).
Motivo più approfondito
Una ragione più profonda potrebbe essere il fatto che Java ha i suoi tipi primitivi, quindi il suo sistema di tipi è diviso tra oggetti e primitive. Forse, se avessero evitato quelli, le cose sarebbero andate diversamente. Con le regole fornite nella sezione precedente, dovrebbero definire esplicitamente la veridicità di ogni singolo primitivo (poiché i primitivi non condividono una super classe e non esiste un null
ben definito per primitivi). Questo si trasformerebbe in un incubo, rapidamente.
Outlook
Bene, e alla fine, forse è solo una preferenza dei progettisti di linguaggi. Ogni lingua sembra girare proprio lì ...
Ad esempio, Ruby non ha tipi primitivi. Tutto, letteralmente tutto, è un oggetto. Hanno un tempo molto semplice per assicurarsi che ogni oggetto abbia un determinato metodo.
Ruby cerca la verità su tutti i tipi di oggetti che puoi lanciare. È interessante notare che non ha ancora il tipo boolean
(perché non ha primitive), e non ha nemmeno Boolean
di classe. Se chiedi quale classe ha il valore true
(facilmente disponibile con true.class
), ottieni TrueClass
. Quella classe ha effettivamente metodi, vale a dire i 4 operatori per i booleani ( | & ^ ==
). Qui, if
considera il suo valore falsey se e solo se è false
o nil
(il null
di Ruby). Tutto il resto è vero. Quindi, 0
o ""
sono entrambi veri.
Sarebbe stato banale per loro creare un metodo Object#truthy?
che potesse essere implementato per qualsiasi classe e restituire una verità individuale. Ad esempio, String#truthy?
avrebbe potuto essere implementato per essere vero per stringhe non vuote o quant'altro. Non lo fecero, anche se Ruby è l'antitesi di Java nella maggior parte dei dipartimenti (digitazione dinamica con mixin, classi di riapertura e tutto il resto).
Il che potrebbe sorprendere un programmatore Perl abituato a $value <> 0 || length($value)>0 || defined($value)
a essere sincero. E così via.
Inserisci SQL con la sua convenzione che null
all'interno di qualsiasi espressione lo rende automaticamente falso, a prescindere da cosa. Quindi (null==null) = false
. In Ruby, (nil==nil) = true
. Momenti felici.