types incompatibles: int ne peut pas être converti en booléen
Je suis intéressé à savoir pourquoi C le permet et java pas. Par conséquent, je m'intéresse au système de types de la langue, en particulier à sa force.
Votre question comporte deux parties:
Pourquoi ne pas convertir Java int
à boolean
?
Cela revient à dire que Java doit être aussi explicite que possible. Il est très statique, très "en face" avec son système de types. Les éléments qui sont automatiquement typés dans d'autres langues ne le sont pas, en Java. Vous devez int a=(int)0.5
aussi écrire . La conversion float
en int
perdrait des informations; même que la conversion int
en boolean
et serait donc sujette à erreur. En outre, ils auraient dû spécifier beaucoup de combinaisons. Bien sûr, ces choses semblent évidentes, mais elles avaient pour but de pécher par excès de prudence.
Oh, et comparé à d’autres langages, Java était extrêmement précis dans ses spécifications, car le bytecode n’était pas simplement un détail d’implémentation interne. Ils devraient spécifier toutes les interactions, précisément. Énorme entreprise.
Pourquoi n'accepte if
pas d'autres types queboolean
?
if
pourrait parfaitement être défini comme autoriser d’autres types que boolean
. Il pourrait avoir une définition disant que les éléments suivants sont équivalents:
true
int != 0
String
avec .length>0
- Toute autre référence d'objet non
null
(et non Boolean
avec une valeur false
).
- Ou même: toute autre référence d'objet non
null
et dont la méthode Object.check_if
(inventée par moi juste pour cette occasion) retourne true
.
Ils ne l'ont pas fait; ils n'en avaient pas vraiment besoin et ils voulaient qu'il soit aussi robuste, statique, transparent, facile à lire, etc. Pas de fonctionnalités implicites. De plus, l'implémentation serait assez complexe, je suis sûr, de devoir tester chaque valeur dans tous les cas possibles, donc les performances ont peut-être joué un petit facteur (Java était jadis peu utilisé sur les ordinateurs de cette journée; rappelez-vous Il n’existait pas de compilateurs JIT avec les premières versions, du moins pas sur les ordinateurs que j’avais utilisés à l’époque).
Raison plus profonde
Une raison plus profonde pourrait bien être le fait que Java a ses types primitifs, son système de types est donc partagé entre des objets et des primitives. Peut-être que s'ils avaient évité cela, les choses se seraient passées autrement. Avec les règles données dans la section précédente, ils devraient définir la véracité de chaque primitive de manière explicite (puisque les primitives ne partagent pas une super classe et qu'il n'y a pas de définition précise null
pour les primitives). Cela se transformerait en un cauchemar, rapidement.
Perspective
Eh bien, et au final, c'est peut-être une préférence des concepteurs de langage. Chaque langue semble s'y frayer un chemin ...
Par exemple, Ruby n'a pas de types primitifs. Tout, littéralement tout, est un objet. Ils ont beaucoup de facilité à s'assurer que chaque objet a une certaine méthode.
Ruby recherche la vérité sur tous les types d'objets que vous pouvez lui lancer. Chose intéressante, il n’a toujours pas de boolean
type (car il n’a pas de primitives) et il n’a pas non plus de Boolean
classe. Si vous demandez quelle classe a la valeur true
(facilement disponible avec true.class
), vous obtenez TrueClass
. Cette classe a effectivement des méthodes, à savoir les 4 opérateurs pour les booléens ( | & ^ ==
). Ici, if
considère sa valeur falsey si et seulement si c'est false
ou nil
(le null
de Ruby). Tout le reste est vrai. Donc, 0
ou ""
sont les deux vrais.
Il aurait été trivial pour eux de créer une méthode Object#truthy?
pouvant être mise en œuvre pour n’importe quelle classe et de restituer une vérité individuelle. Par exemple, String#truthy?
aurait pu être implémenté pour être vrai pour des chaînes non vides, ou autre chose. Ils ne l’ont pas fait, même si Ruby est l’antithèse de Java dans la plupart des départements (typage dynamique de canards avec mixin, réouverture de classes, etc.).
Ce qui pourrait surprendre un programmeur Perl habitué à $value <> 0 || length($value)>0 || defined($value)
la vérité. Etc.
Entrez SQL avec sa convention qui, null
à l'intérieur de n'importe quelle expression, la rend automatiquement fausse, quoi qu'il arrive. Donc (null==null) = false
. Dans Ruby, (nil==nil) = true
. Moments heureux.