Si la question semble être la suivante: "Comment renvoyer deux informations sans relation d'une méthode qui renvoie un seul int? Je ne veux jamais vérifier mes valeurs de retour et les valeurs NULL sont incorrectes, ne les utilisez pas."
Regardons ce que vous voulez transmettre. Vous transmettez soit un int, soit un non- raisonnement pour lequel vous ne pouvez pas donner l'int. La question affirme qu'il n'y aura que deux raisons, mais quiconque a déjà fait une énumération sait que la liste s'allongera. La possibilité de spécifier d’autres raisons est tout à fait logique.
Au départ, cela pourrait donc être un bon argument pour lancer une exception.
Lorsque vous souhaitez indiquer à l'appelant quelque chose de spécial qui ne figure pas dans le type de retour, les exceptions constituent souvent le système approprié: les exceptions ne concernent pas uniquement les états d'erreur et vous permettent de renvoyer une grande quantité de contexte et de raisons pour expliquer pourquoi vous pouvez simplement le faire. t int aujourd'hui.
Et c’est le SEUL système qui vous permet de renvoyer des ints garantis-valides et garantit que chaque opérateur int et chaque méthode prenant ints peut accepter la valeur de retour de cette méthode sans avoir à rechercher des valeurs non valides telles que null ou des valeurs magiques.
Mais les exceptions ne sont réellement qu'une solution valable si, comme son nom l'indique, il s'agit d'un cas exceptionnel et non du cours normal des affaires.
Et essayer / attraper et manipuler équivaut tout autant à un passe-partout qu'un contrôle nul, ce à quoi on s'est objecté au départ.
Et si l'appelant ne contient pas try / catch, l'appelant doit le faire, et ainsi de suite.
Un second passage naïf consiste à dire "C'est une mesure. Les mesures de distance négatives sont peu probables." Donc, pour certaines mesures Y, vous pouvez simplement avoir des consts pour
- -1 = inconnu,
- -2 = impossible à mesurer,
- -3 = a refusé de répondre,
- -4 = connu mais confidentiel,
- -5 = varie en fonction de la phase de la lune, voir tableau 5a,
- -6 = quatre dimensions, mesures indiquées dans le titre,
- -7 = erreur de lecture du système de fichiers,
- -8 = réservé pour une utilisation future,
- -9 = carré / cube si Y est identique à X,
- -10 = est un écran de contrôle et n'utilise donc pas les mesures X, Y: utilisez X comme diagonale de l'écran,
- -11 = a écrit les mesures au verso d'un reçu et il a été blanchi pour le rendre illisible mais je pense que c'était 5 ou 17
- -12 = ... vous avez l'idée.
C’est comme cela que l’on fait dans beaucoup d’anciens systèmes C, et même dans les systèmes modernes où il existe une contrainte réelle pour int, et que vous ne pouvez pas l’envelopper dans une structure ou une monade quelconque.
Si les mesures peuvent être négatives, vous devez simplement augmenter la taille de votre type de données (par exemple, long int) et faire en sorte que les valeurs magiques soient supérieures à la plage de int, et idéalement, commencez par une valeur qui apparaîtra clairement dans un débogueur.
Il y a de bonnes raisons de les avoir comme variable distincte, plutôt que d'avoir simplement des nombres magiques, cependant. Par exemple, dactylographie stricte, maintenabilité et conformité aux attentes.
Dans notre troisième tentative, nous examinons donc les cas où il est normal que des valeurs non int soient utilisées. Par exemple, si une collection de ces valeurs peut contenir plusieurs entrées non entières. Cela signifie qu'un gestionnaire d'exceptions peut être une mauvaise approche.
Dans ce cas, il semble judicieux de disposer d’une structure qui passe l’int, et de la logique. Encore une fois, cette justification peut simplement être une constante comme ci-dessus, mais au lieu de conserver les deux dans le même int, vous les stockez en tant que parties distinctes d'une structure. Au départ, nous avons la règle que si la justification est définie, l'int ne sera pas défini. Mais nous ne sommes plus liés à cette règle; nous pouvons également fournir des justifications pour les nombres valides, le cas échéant.
Quoi qu'il en soit, chaque fois que vous l'appelez, vous avez toujours besoin d'un passe-partout pour tester la justification de voir si l'int est valide, puis retirez-vous et utilisez la partie int si la justification nous le permet.
C'est là que vous devez étudier votre raisonnement derrière "ne pas utiliser null".
Comme les exceptions, null signifie un état exceptionnel.
Si un appelant appelle cette méthode et ignore complètement la partie "justification" de la structure, attend un numéro sans traitement d'erreur et obtient un zéro, il le traitera comme un nombre et se trompera. Si cela donne un nombre magique, il le traitera comme un nombre et se trompera. Mais si elle devient nulle, elle tombera , comme il se doit.
Donc, chaque fois que vous appelez cette méthode, vous devez vérifier si sa valeur de retour est vérifiée. Cependant, vous manipulez les valeurs non valides, qu'elles soient dans la bande ou hors bande, try / catch, en recherchant un composant "raisonnement" dans la structure, pour un nombre magique, ou en vérifiant un int pour un null ...
L'alternative, pour gérer la multiplication d'une sortie pouvant contenir un int invalide et une logique telle que "Mon chien a mangé cette mesure", consiste à surcharger l'opérateur de multiplication de cette structure.
... et surchargez ensuite tous les autres opérateurs de votre application susceptibles d'être appliqués à ces données.
... Et ensuite surcharger toutes les méthodes qui pourraient prendre ints.
... Et toutes ces surcharges devront toujours contenir des vérifications pour les entrées non valides, afin que vous puissiez traiter le type de retour de cette méthode comme s'il s'agissait toujours d'un entier valide au moment où vous l'appelez.
La prémisse originale est donc fausse de différentes manières:
- Si vous avez des valeurs non valides, vous ne pouvez pas éviter de vérifier ces valeurs à tout moment dans le code où vous gérez les valeurs.
- Si vous retournez autre chose qu'un int, vous ne retournez pas un int, vous ne pouvez donc pas le traiter comme un int. La surcharge d'opérateur vous permet de faire semblant , mais c'est juste faire semblant.
- Un int avec des nombres magiques (y compris NULL, NAN, Inf ...) n'est plus vraiment un int, c'est une structure de pauvre.
- Éviter les valeurs nulles ne rendra pas le code plus robuste, il masquera simplement les problèmes liés aux ints ou les déplacera dans une structure complexe de gestion des exceptions.