tipi incompatibili: int non può essere convertito in booleano
Sono interessato al motivo per cui C lo consente e Java no. Pertanto, sono interessato al sistema di tipi di linguaggio, in particolare alla sua forza.
Ci sono due parti alla tua domanda:
Perché Java non si converte int
in boolean
?
Questo si riduce a Java inteso per essere il più esplicito possibile. È molto statico, molto "in faccia" con il suo sistema di tipi. Le cose che vengono automaticamente scritte in altre lingue non sono così, in Java. Devi anche scrivere int a=(int)0.5
. La conversione float
in int
perderebbe informazioni; uguale alla conversione int
in boolean
e sarebbe quindi soggetto a errori. Inoltre, avrebbero dovuto specificare molte combinazioni. Certo, queste cose sembrano ovvie, ma intendevano sbagliare dal lato della cautela.
Oh, e rispetto ad altre lingue, Java era estremamente preciso nelle sue specifiche, poiché il bytecode non era solo un dettaglio di implementazione interno. Dovrebbero specificare tutte le interazioni, precisamente. Grande impresa.
Perché if
non accetta altri tipi di boolean
?
if
potrebbe essere perfettamente definito per consentire altri tipi di boolean
. Potrebbe avere una definizione che dice quanto segue sono equivalenti:
true
int != 0
String
con .length>0
- Qualsiasi altro riferimento a oggetto che non sia
null
(e non un Boolean
valore con false
).
- O anche: qualsiasi altro riferimento a un oggetto che non è
null
e il cui metodo Object.check_if
(inventato da me solo per questa occasione) ritorna true
.
Non lo fecero; non c'era bisogno reale, e volevano che fosse il più robusto, statico, trasparente, di facile lettura, ecc. Nessuna funzionalità implicita. Inoltre, l'implementazione sarebbe piuttosto complessa, ne sono sicuro, dovendo testare ogni valore per tutti i possibili casi, quindi le prestazioni potrebbero anche aver giocato un piccolo fattore (Java era un po 'sloooow sui computer di quel giorno; ricorda lì non era un compilatore JIT con le prime versioni, almeno non sui computer che ho usato allora).
Motivo più profondo
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 primitivi. Forse, se avessero evitato quelli, le cose sarebbero andate diversamente. Con le regole fornite nella sezione precedente, dovrebbero definire esplicitamente la veridicità di ogni singola primitiva (dal momento che le primitive non condividono una superclasse e non esiste una definizione ben definita null
per le primitive). Ciò si trasformerebbe in un incubo, rapidamente.
prospettiva
Bene, e alla fine, forse è solo una preferenza per i progettisti del linguaggio. Ogni lingua sembra girare a modo suo lì ...
Ad esempio, Ruby non ha tipi primitivi. Tutto, letteralmente tutto, è un oggetto. Si divertono molto facendo in modo che ogni oggetto abbia un certo metodo.
Ruby cerca la verità su tutti i tipi di oggetti che puoi lanciare contro di esso. È interessante notare che non ha ancora alcun boolean
tipo (perché non ha primitivi) e non ha nemmeno Boolean
classe. Se chiedi quale classe ha il valore true
(facilmente disponibile con true.class
), ottieni TrueClass
. Quella classe ha effettivamente dei metodi, vale a dire i 4 operatori per i booleani ( | & ^ ==
). Qui, if
considera il suo valore falso se e solo se è uno 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 l'hanno fatto, anche se Ruby è l'antitesi di Java nella maggior parte dei dipartimenti (digitazione dinamica delle anatre 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)
essere sincero. E così via.
Inserisci SQL con la sua convenzione che null
all'interno di qualsiasi espressione lo rende automaticamente falso, non importa quale. Così (null==null) = false
. In Ruby, (nil==nil) = true
. Tempi felici.