Pourquoi Java n'autorise-t-il pas les conditions numériques comme if (5) {…} si C le fait?

33

J'ai ces deux petits programmes:

C

#include <stdio.h>
int main()
{
    if (5) {
        printf("true\n");
    }
    else {
        printf("false\n");
    }

    return 0;
}

Java

class type_system {
   public static void main(String args[]) {
       if (5) {
           System.out.println("true");
       }
       else {
           System.out.println("false");
       }
   }
}

qui rapporte le message d'erreur:

type_system.java:4: error: incompatible types: int cannot be converted to boolean
       if (5) {
           ^
1 error

Ma compréhension

Jusqu'ici, j'ai compris cet exemple comme une démonstration des différents systèmes de types. C est plus faiblement typé et permet la conversion de int en booléen sans erreur. Java est plus fortement typé et échoue, car aucune conversation implicite n'est autorisée.

Par conséquent, ma question: Où ai-je mal compris les choses?

Ce que je ne cherche pas

Ma question n'est pas liée au style de codage incorrect. Je sais que c'est mauvais, mais je m'interroge sur la raison pour laquelle C l'autorise et non sur Java. Par conséquent, je m'intéresse au système de types de la langue, en particulier à sa force.

toogley
la source
22
@toogley: Qu'est-ce que vous voulez savoir en particulier sur le système de types Java? Le système de types ne le permet pas car la spécification de langage l'interdit. Les raisons pour lesquelles C le permet et Java n’a pas tout à voir avec ce qui est considéré comme acceptable dans les deux langues. Le comportement résultant des systèmes de types en est l’effet , pas la cause.
Robert Harvey
8
@ toogley: pourquoi penses-tu avoir mal compris quelque chose? En relisant le texte, je ne comprends pas votre question.
Doc Brown
26
En réalité, ce n'est pas un exemple de typage faible en C. Dans le passé (C89), C n'avait même pas de type booléen, aussi toutes les opérations "booléennes" opéraient-elles en réalité sur des intvaleurs. Un exemple plus approprié serait if (pointer).
Rufflewind
5
J'ai voté parce qu'il ne semble pas que beaucoup de recherches aient été faites pour essayer de comprendre cela.
jpmc26
11
Il semble que la question initiale posée diffère un peu de la version modifiée (c’est pourquoi certains commentaires et réponses semblent répondre à une question différente). Dans sa forme actuelle, il ne semble pas y avoir de question ici. Quel malentendu? Java se comporte exactement comme vous le pensez.
jamesdlin

Réponses:

134

1. C et Java sont des langues différentes

Le fait qu'ils se comportent différemment ne devrait pas être terriblement surprenant.

2. C ne fait aucune conversion de intàbool

Comment pourrait-il? C n’avait même pas de booltype à convertir avant 1999 . C a été créé au début des années 1970 et en iffaisait partie avant même d'être C, à l'époque où il s'agissait simplement d'une série de modifications apportées à B 1 .

ifn'était pas simplement NOPen C depuis près de 30 ans. Il agissait directement sur les valeurs numériques. Le verbiage dans la norme C ( lien PDF ), même plus d'une décennie après l'introduction de bools en C, spécifie toujours le comportement de if(p 148) et ?:(p 100) en utilisant les termes "inégalé à 0" et "égal à 0 "plutôt que les termes booléens" true "ou" false "ou quelque chose de similaire.

Idéalement, ...

3. ... les chiffres correspondent exactement aux instructions du processeur.

JZet JNZsont vos instructions d’assemblage x86 de base pour les branchements conditionnels. Les abréviations sont " J UMP si Z ero" et " J UMP si N ot Z ero". Les équivalents de la PDP-11, où C est issue, sont BEQ( " B ranch si EQ uel ") et BNE(" B ranch si N ot E Qual").

Ces instructions vérifient si l'opération précédente a généré un zéro ou non et saute (ou non) en conséquence.

4. Java accorde beaucoup plus d'importance à la sécurité que jamais 2

Et, soucieux de la sécurité, ils ont décidé que la limitation ifà booleans valait le coût (tant pour la mise en œuvre d'une telle restriction que pour les coûts d'opportunité qui en résultent).


1. B n'a même pas de types du tout. Les langues d'assemblage ne le sont généralement pas non plus. Pourtant, les langages B et d’assemblage parviennent très bien à gérer les branches.

2. Selon les mots de Dennis Ritchie, décrivant les modifications prévues à B qui sont devenues C (c'est moi qui souligne):

... il semblait qu'un schéma de frappe était nécessaire pour gérer les caractères et l'adressage d'octets, et pour préparer le matériel à virgule flottante à venir. D'autres problèmes, notamment la sécurité des types et la vérification de l'interface, ne semblaient pas aussi importants qu'ils ne le sont devenus par la suite.

8bittree
la source
13
Beau point sur les expressions booléennes en C mappant directement sur les instructions du processeur. Je n'y avais pas pensé avant.
Robert Harvey
17
Je pense que le point 4 est trompeur dans la mesure où il semble impliquer que C a quelques idées de sécurité ... C vous laissera faire tout ce que vous voulez: C suppose que vous savez ce que vous faites, avec des résultats souvent catastrophiques.
TemporalWolf
13
@TemporalWolf Vous déclarez que, comme si C vous laisser faire ce que vous voulez était mauvais. La différence à mon avis est que C a été écrit pour les programmeurs et une compétence de base est attendue. Java est écrit pour les singes de code et si vous pouvez taper, vous pouvez le programmer. Souvent de façon spectaculaire, mais qui s'en soucie? Je n'oublierai jamais le moment où un enseignant de la classe d'introduction à Java que je devais intégrer à mon programme de mineur CS a souligné que l'utilisation de la récursivité pour calculer les nombres de Fibonnaci pourrait être utile car elle était "facile à écrire". C'est pourquoi nous avons le logiciel que nous avons.
DRF
25
@DRF Un de mes professeurs pour une classe de réseautage C a déclaré: "C est comme une boîte de grenades à main avec toutes les épingles retirées." Vous avez beaucoup de pouvoir, mais il est essentiellement garanti que votre visage explose. Dans la grande majorité des cas, cela ne vaut pas la peine, et vous serez beaucoup plus productif avec un langage de niveau supérieur. Ai-je transcodé Python en hacky C-twiddling pour obtenir une augmentation de 6 ordres de grandeur de la vitesse? Oui, oui j'ai. Mais c'est l'exception et non la règle. Je peux accomplir en une journée en Python ce qui me prendrait deux semaines en C ... et je suis un bon programmeur C.
TemporalWolf
11
@DRF Compte tenu de la prévalence des exploits de débordement de mémoire tampon dans les logiciels grand public développés par de grandes sociétés, même les programmeurs disposant des compétences de base ne peuvent apparemment pas faire confiance à leurs lecteurs.
Réintégrer Monica
14

C 2011 projet en ligne

6.8.4.1 L' ifinstruction

Contraintes

1 L'expression de contrôle d'une ifinstruction doit être de type scalaire.

Sémantique

2 Dans les deux formes, le premier sous-dénombrement est exécuté si l'expression est différente de 0. Le elsesous-dénombrement est exécuté si l'expression est égale à 0. Si le premier sous-dénombrement est atteint via une étiquette, le deuxième Non exécuté.

3 An elseest associé au précédent lexical le plus proche si cela est autorisé par la syntaxe.

Notez que cette clause spécifie uniquement que l'expression de contrôle doit avoir un type scalaire ( char/ short/ int/ long/ etc.), Pas spécifiquement un type booléen. Une branche est exécutée si l'expression de contrôle a une valeur différente de zéro.

Comparez cela avec

Spécification du langage Java SE 8

14.9 L' ifinstruction

L' ifinstruction permet l'exécution conditionnelle d'une instruction ou le choix conditionnel de deux instructions, en exécutant l'une ou l'autre mais pas les deux.
    IfThenStatement :
        si (  Expression ) Statement

    IfThenElseStatement :
        if ( Expression ) StatementNoShortIf else Statement

    IfThenElseStatementNoShortIf :
        if ( Expression ) StatementNoShortIf else StatementNoShortIf
L' expression doit avoir le typeboolean ou Boolean, sinon une erreur de compilation se produit.

Java, OTOH, requiert spécifiquement que l'expression de contrôle dans une ifinstruction ait un type booléen.

Donc, il ne s'agit pas de typage faible ou fort, mais de ce que chaque définition de langage respective spécifie comme expression de contrôle valide.

modifier

En ce qui concerne la raison pour laquelle les langues sont différentes à cet égard, plusieurs points:

  1. C est dérivé de B, qui est un langage "sans type" - en gros, tout était un mot de 32 à 36 bits (selon le matériel), et toutes les opérations arithmétiques étaient des opérations entières. Le système de type de C était verrouillé un à un, de sorte que ...

  2. C n'avait pas de type booléen distinct jusqu'à la version 1999 du langage. C a simplement suivi la convention B consistant à utiliser zéro pour représenter falseet non-zéro pour représenter true.

  3. Java, qui date de 20 à 20 ans, a été conçu spécifiquement pour remédier à certaines des faiblesses de C et C ++. Nul doute que renforcer la restriction sur ce qui pourrait être une expression de contrôle dans une ifdéclaration en faisait partie.

  4. Il n'y a aucune raison de s'attendre à ce que deux langages de programmation fassent les choses de la même manière. Même des langages aussi proches que C et C ++ divergent de manière intéressante, de sorte que vous pouvez avoir des programmes C juridiques qui ne sont pas des programmes C ++ légaux, ou qui sont des programmes C ++ légaux mais avec une sémantique différente, etc.

John Bode
la source
Trop triste, je ne peux pas marquer deux réponses comme "acceptées" ..
toogley
1
Oui, c’est une bonne reformulation de la question. Mais la question demandait pourquoi il y avait cette différence entre les deux langues. Vous n'avez pas du tout abordé cette question.
Dawood dit réintégrer Monica
@DawoodibnKareem: La question était de savoir pourquoi C permettait la conversion de intvers booleanalors que Java ne le permettait pas. La réponse est qu’il n’ya pas de conversion de ce type en C. Les langues sont différentes parce qu’elles sont différentes.
John Bode
Oui, "il ne s'agit pas de typage faible ou puissant". Il suffit de regarder la boxe automatique et le déballage automatique. Si C en avait, cela ne pourrait permettre aucun type scalaire non plus.
Déduplicateur
5

Beaucoup de réponses semblent cibler l'expression d'affectation incorporée qui se trouve dans l'expression conditionnelle. (Bien que ce soit un piège potentiel connu, ce n'est pas la source du message d'erreur Java dans ce cas.)

C’est peut-être parce que le PO n’a pas publié le message d’erreur réel et que le ^curseur pointe directement sur le= opérateur de l'affectation.

Cependant, le compilateur pointe vers le = car c'est l'opérateur qui produit la valeur finale (et donc le type final) de l'expression que voit le conditionnel.

Il se plaint de tester une valeur non booléenne, avec le type d'erreur suivant:

erreur: types incompatibles: int ne peut pas être converti en booléen

Le test des entiers, bien que parfois pratique, est considéré comme un piège que les concepteurs de Java ont choisi d'éviter. Après tout, Java a un vrai type de données booléen , ce que C n’a pas (il n’a pas de type booléen) .

Ceci s'applique également aux pointeurs de test de C pour la valeur null / non-null via if (p) ...et if (!p) ..., ce que Java ne permet pas non plus de demander à un opérateur de comparaison explicite d'obtenir le booléen requis.

Erik Eidt
la source
1
C n'avoir un type booléen. Mais c'est plus récent que la déclaration. if
MSalters
3
La valeur booléenne de @MSalters C est toujours un entier sous couvert, donc vous pouvez le faire bool b = ...; int v = 5 + b;. Ceci est différent des langues avec un type booléen complet qui ne peuvent pas être utilisées en arithmétique.
Jules
Le booléen de C n'est qu'un très petit entier. "true" et "false" pourraient facilement être définis avec des macros ou autres.
Oskar Skog
4
@ Jules: Vous venez de souligner que C a une sécurité de type faible. Ce n’est pas parce qu’un type booléen est converti en un nombre entier qu’il s’agit d’ un type entier. Selon votre logique, les types entiers seraient des types à virgule flottante car ils int v = 5; float f = 2.0 + v;sont légaux en C.
MSalters
1
@MSalters _Boolest en fait l'un des types entiers standard non signés définis par la norme (voir 6.2.5 / 6).
Ruslan
2

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.5aussi écrire . La conversion floaten intperdrait des informations; même que la conversion inten booleanet 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 ifpas d'autres types queboolean ?

ifpourrait 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 Booleanavec une valeur false).
  • Ou même: toute autre référence d'objet non nullet 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 nullpour 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 booleantype (car il n’a pas de primitives) et il n’a pas non plus de Booleanclasse. 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, ifconsidère sa valeur falsey si et seulement si c'est falseou nil(le nullde Ruby). Tout le reste est vrai. Donc, 0ou ""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.

AnoE
la source
En fait, ((int)3) * ((float)2.5)c'est assez bien défini en Java (c'est le cas 7.5f).
Paŭlo Ebermann,
Vous avez raison, @ PaŭloEbermann, j'ai supprimé cet exemple.
AnoE
Woah There ... aimerait recevoir les commentaires des électeurs votants et de celui qui a voté en faveur de la suppression de la réponse.
AnoE
En fait, la conversion de inten floatperd également des informations en général. Java interdit-il également une telle diffusion implicite?
Ruslan,
@Ruslan no (idem pour long → double) - J'imagine que l'idée est que la perte potentielle d'informations ne se produit que dans les endroits les moins significatifs et ne se produit que dans les cas jugés moins importants (valeurs entières assez grandes).
Paŭlo Ebermann
1

Outre les autres bonnes réponses, j'aimerais parler de la cohérence entre les langues.

Lorsque nous pensons à une instruction if mathématiquement pure, nous comprenons que la condition peut être vraie ou fausse, pas d'autre valeur. Tous les principaux langages de programmation respectent cet idéal mathématique; Si vous donnez une valeur booléenne true / false à une instruction if, vous pouvez vous attendre à voir un comportement intuitif et cohérent tout le temps.

Jusqu'ici tout va bien. C'est ce que Java implémente, et seulement ce que Java implémente.

D'autres langues tentent d'apporter des commodités pour les valeurs non booléennes. Par exemple:

  • Suppose nest un entier. Définissez maintenant if (n)le raccourci pour if (n != 0).
  • Supposer xest un nombre à virgule flottante. Définissez maintenant if (x)le raccourci pour if (x != 0 && !isNaN(x)).
  • Suppose pest un type de pointeur. Définissez maintenant if (p)le raccourci pour if (p != null).
  • Suppose sest un type de chaîne. Maintenant, définir if (s)pour êtreif (s != null && s != "") .
  • Suppose aest un type de tableau. Définissez maintenant if (a)pour être if (a != null && a.length > 0).

Cette idée de fournir des si-tests abrégés semble bonne en surface ... jusqu'à ce que vous rencontriez des différences de conceptions et d'opinions:

  • if (0)est traité comme faux en C, Python, JavaScript; mais traité comme vrai dans Ruby.
  • if ([]) est traité comme faux en Python mais vrai en JavaScript.

Chaque langue a ses propres bonnes raisons de traiter les expressions d’une manière ou d’une autre. (Par exemple, les seules valeurs de fausseté dans Ruby sont falseet nil, par conséquent, 0sont la vérité.)

Java a adopté une conception explicite pour vous obliger à fournir une valeur booléenne à une instruction if. Si vous avez rapidement traduit du code de C / Ruby / Python vers Java, vous ne pouvez pas laisser les tests if lax inchangés; vous devez écrire explicitement la condition en Java. Prendre un moment pour faire une pause et réfléchir peut vous éviter des erreurs négligentes.

Nayuki
la source
1
Savez-vous que x != 0c'est la même chose x != 0 && !isNaN(x)? En outre, c'est normalement s != nullpour les pointeurs, mais autre chose pour les non-pointeurs.
Déduplicateur
@Déduplicateur dans quelle langue est-ce la même chose?
Paŭlo Ebermann,
1
En utilisant IEEE754, NaN ≠ 0. NaN ≠ rien du tout. Donc si (x) exécuterait, et si (! X) exécuterait aussi bien ...
gnasher729
0

Eh bien, chaque type scalaire en C, pointeur, booléen (depuis C99), nombre (virgule flottante ou non) et énumération (en raison de la correspondance directe avec des nombres) a une valeur de falsey "naturelle", ce qui est suffisant pour toute expression conditionnelle .

Java en a aussi (même si les pointeurs Java sont appelés des références et sont fortement restreints), mais il a introduit l'auto-boxing dans Java 5.0 qui brouille les eaux de façon inacceptable. En outre, les programmeurs Java exhortent la valeur intrinsèque de la saisie plus fréquente.

L'une erreur qui a donné naissance le débat se limitant des expressions conditionnelles au type booléen est la faute de frappe d'écrire une mission où une comparaison a été prévu, ce qui est pas adressée en limitant le type d'expressions conditionnelles du tout , mais en interdisant l' utilisation d'une nue cession d'expression pour sa valeur.

Tout compilateur moderne en C ou C ++ gère cela facilement, en donnant un avertissement ou une erreur pour de telles constructions douteuses si demandé.
Pour les cas où c'est exactement ce qui était prévu, l'ajout de parenthèses aide.

Pour résumer, restreindre à booléen (et son équivalent encadré en Java) ressemble à une tentative infructueuse de création d'une classe de fautes de frappe provoquée par le choix =d'affectation des erreurs de compilation.

Déduplicateur
la source
L'utilisation ==d'opérandes booléens, dont la première est une variable (qui pourrait alors être typée =), ifest beaucoup moins fréquente à l' intérieur que d'autres types, je dirais, ce n'est donc qu'une tentative semi-échouée.
Paŭlo Ebermann,
Avoir 0.0 -> false et toute valeur autre que 0.0 -> true ne me semble pas "naturel".
gnasher729
@ PaŭloEbermann: Un résultat partiel avec des effets secondaires malheureux, bien qu'il existe un moyen facile d'atteindre l'objectif sans effets secondaires, est un échec évident dans mon livre.
Déduplicateur
Vous manquez les autres raisons. Qu'en est- il de la valeur de truthy "", (Object) "", 0.0, -0.0, NaN, des tableaux vides, et Boolean.FALSE? Le dernier en particulier est amusant, car c'est un pointeur non nul (true) qui défait unbox. +++ Je déteste aussi écrire if (o != null), mais me garder quelques caractères chaque jour et me laisser passer une demi-journée à déboguer mon expression "intelligente" n’est pas une bonne affaire. Cela dit, j'aimerais beaucoup voir un moyen terme pour Java: des règles plus généreuses, mais ne laissant aucune ambiguïté.
Maaartinus
@maaartinus: Comme je l'ai dit, l'introduction du déballage automatique dans Java 5.0 signifiait que s'ils attribuaient une valeur de vérité correspondant à la valeur null-ness aux pointeurs, ils auraient tout à fait un problème. Mais c’est un problème de boxe automatique, pas d’autre chose. Un langage sans boxe automatique comme C est heureusement libéré de cela.
Déduplicateur
-1

Ma question n'est pas liée au style de codage incorrect. Je sais que c'est mauvais, mais je comprends pourquoi C ne le permet pas et java pas.

Les deux objectifs de conception de Java étaient:

  1. Permettez au développeur de se concentrer sur le problème de l'entreprise. Rendez les choses plus simples et moins sujettes aux erreurs, par exemple la récupération de place afin que les développeurs n'aient pas à se concentrer sur les fuites de mémoire.

  2. Portable entre les plates-formes, par exemple, exécuter sur n'importe quel ordinateur avec n'importe quel processeur.

L'utilisation de l'affectation en tant qu'expression était connue pour causer beaucoup de bugs dus aux fautes de frappe, donc sous l'objectif n ° 1 ci-dessus, il n'est pas autorisé de la façon dont vous essayez de l'utiliser.

De plus, déduire que toute valeur non nulle = vraie et toute valeur nulle = faux n'est pas nécessairement portable (oui, croyez-le ou non, certains systèmes traitent 0 comme vrai et 1 comme faux ), donc sous l'objectif n ° 2 ci-dessus, n'est pas autorisé implicitement . Vous pouvez toujours lancer explicitement bien sûr.

John Wu
la source
4
Sauf si cela a été ajouté dans Java 8, il n'y a pas de conversion explicite entre les types numériques et les booléens. Pour convertir une valeur numérique en booléen, vous devez utiliser un opérateur de comparaison. Pour convertir une valeur booléenne en valeur numérique, vous utilisez généralement l'opérateur ternaire.
Peter Taylor
Vous pouvez faire un cas pour interdire l'utilisation d'une affectation pour sa valeur en raison de ces erreurs de frappe. Mais compte tenu de la fréquence à laquelle vous voyez == true et == false en Java, limiter l’expression de contrôle au type booléen (éventuellement encadré) n’aide en rien.
Déduplicateur
Java assurerait trivialement la portabilité par rapport à "certains systèmes considèrent 0 comme vrai et 1 comme faux", car c'est le zéro de Java et le faux de Java. Peu importe ce que le système d'exploitation en pense.
Maaartinus
-1

À titre d’exemple, c’est ce que font les autres langages: Swift requiert une expression d’un type prenant en charge le protocole "BooleanType", ce qui signifie qu’il doit avoir une méthode "boolValue". Le type "bool" supporte évidemment ce protocole et vous pouvez créer vos propres types le supportant. Les types entiers ne supportent pas ce protocole.

Dans les versions antérieures des langues, les types facultatifs étaient compatibles avec "BooleanType", vous pouviez donc écrire "if x" au lieu de "if x! = Nil". Ce qui rendait l'utilisation d'un "bool facultatif" très déroutant. Un booléen optionnel a les valeurs nil, false ou true et "if b" ne serait pas exécuté si b était nil et exécuté si b était true ou false. Ce n'est plus permis.

Et il semble y avoir un gars qui n'aime pas vraiment ouvrir vos horizons ...

gnasher729
la source