J'ai toujours entendu parler d'une fonction de point de sortie unique comme une mauvaise façon de coder parce que vous perdez en lisibilité et en efficacité. Je n'ai jamais entendu personne discuter de l'autre côté.
Je pensais que cela avait quelque chose à voir avec CS, mais cette question a été posée à cstheory stackexchange.
coding-style
hexagone bob-omb
la source
la source
Réponses:
Il existe différentes écoles de pensée, et cela dépend en grande partie des préférences personnelles.
La première est qu'il est moins déroutant s'il n'y a qu'un seul point de sortie - vous avez un seul chemin à travers la méthode et vous savez où chercher la sortie. Du côté négatif, si vous utilisez l'indentation pour représenter l'imbrication, votre code finit par être massivement indenté vers la droite et il devient très difficile de suivre toutes les portées imbriquées.
Une autre est que vous pouvez vérifier les conditions préalables et quitter tôt au début d'une méthode, de sorte que vous sachiez dans le corps de la méthode que certaines conditions sont vraies, sans que le corps entier de la méthode soit en retrait de 5 miles vers la droite. Cela minimise généralement le nombre d'étendues dont vous devez vous soucier, ce qui rend le code beaucoup plus facile à suivre.
Un troisième est que vous pouvez quitter n'importe où. Auparavant, c'était plus déroutant, mais maintenant que nous avons des éditeurs et des compilateurs de coloration syntaxique qui détectent le code inaccessible, c'est beaucoup plus facile à gérer.
Je suis carrément dans le camp du milieu. Appliquer un point de sortie unique est une restriction inutile ou même contre-productive à mon humble avis, alors que quitter au hasard dans une méthode peut parfois conduire à une logique compliquée difficile à suivre, où il devient difficile de voir si un morceau de code donné sera ou ne sera pas réalisé. Mais "gating" votre méthode permet de simplifier considérablement le corps de la méthode.
la source
singe exit
paradigme à force d'go to
énoncés. De plus, on a la possibilité d'effectuer un post-traitement sous l'Error
étiquette locale de la fonction , ce qui est impossible avec plusieursreturn
s.Ma recommandation générale est que les déclarations de retour devraient, lorsque cela est possible, être situées avant le premier code qui a des effets secondaires, ou après le dernier code qui a des effets secondaires. Je considérerais quelque chose comme:
plus clair que:
Si une certaine condition devait empêcher une fonction de faire quoi que ce soit, je préfère revenir tôt hors de la fonction à un endroit au-dessus du point où la fonction ferait quelque chose. Une fois que la fonction a entrepris des actions avec des effets secondaires, je préfère revenir par le bas, pour préciser que tous les effets secondaires doivent être traités.
la source
ok
variable, me semble être l'approche à retour unique. De plus, le bloc if-else peut être simplement réécrit en:return ok ? 0 : ERR_NOT_OK;
return
au début avant tout le code qui fait tout. En ce qui concerne l'utilisation de l'?:
opérateur, l'écrire sur des lignes séparées permet à de nombreux IDE d'attacher plus facilement un point d'arrêt de débogage au scénario non correct. BTW, la vraie clé du "point de sortie unique" réside dans la compréhension que ce qui compte, c'est que pour chaque appel particulier à une fonction normale, le point de sortie est le point immédiatement après l'appel . De nos jours, les programmeurs tiennent cela pour acquis, mais les choses n'ont pas toujours été ainsi. Dans de rares cas, le code peut devoir se débrouiller sans espace de pile, conduisant à des fonctions ...Le point d'entrée et de sortie unique était le concept original de la programmation structurée par rapport au codage spaghetti étape par étape. Il existe une croyance selon laquelle plusieurs fonctions de point de sortie nécessitent plus de code car vous devez nettoyer correctement les espaces mémoire alloués aux variables. Considérez un scénario dans lequel la fonction alloue des variables (ressources) et la sortie précoce de la fonction et sans nettoyage approprié entraînerait des fuites de ressources. De plus, la construction du nettoyage avant chaque sortie créerait beaucoup de code redondant.
la source
Avec presque tout, cela dépend des besoins du livrable. Dans «l'ancien temps», le code spaghetti avec plusieurs points de retour provoquait des fuites de mémoire, car les codeurs qui préféraient cette méthode ne nettoyaient généralement pas bien. Il y avait aussi des problèmes avec certains compilateurs "perdant" la référence à la variable de retour lorsque la pile était sautée pendant le retour, dans le cas d'un retour d'une portée imbriquée. Le problème le plus général était celui du code rentrant, qui tente de faire en sorte que l'état d'appel d'une fonction soit exactement le même que son état de retour. Les mutateurs de oop ont violé cela et le concept a été mis de côté.
Il existe des livrables, notamment des noyaux, qui ont besoin de la vitesse fournie par plusieurs points de sortie. Ces environnements ont normalement leur propre mémoire et leur propre gestion des processus, de sorte que le risque de fuite est minimisé.
Personnellement, j'aime avoir un point de sortie unique, car je l'utilise souvent pour insérer un point d'arrêt sur l'instruction de retour et effectuer une inspection du code de la façon dont le code a déterminé cette solution. Je pourrais simplement aller à l'entrée et passer à travers, ce que je fais avec des solutions largement imbriquées et récursives. En tant que réviseur de code, plusieurs retours dans une fonction nécessitent une analyse beaucoup plus approfondie - donc si vous le faites pour accélérer l'implémentation, vous volez Peter pour sauver Paul. Il faudra plus de temps pour les révisions de code, ce qui invalidera la présomption de mise en œuvre efficace.
- 2 cents
Veuillez consulter ce document pour plus de détails: NISTIR 5459
la source
multiple returns in a function requires a much deeper analysis
seulement si la fonction est déjà énorme (> 1 écran), sinon cela facilite l'analyseÀ mon avis, le conseil de quitter une fonction (ou une autre structure de contrôle) à un seul moment est souvent survendu. Deux raisons sont généralement données pour quitter à un seul moment:
La deuxième raison est subtile et a un certain mérite, surtout si la fonction renvoie une grande structure de données. Cependant, je ne m'en soucierais pas trop, sauf ...
Si vous êtes étudiant, vous souhaitez obtenir les meilleures notes dans votre classe. Faites ce que l'instructeur préfère. Il a probablement une bonne raison de son point de vue; alors, à tout le moins, vous apprendrez son point de vue. Cela a une valeur en soi.
Bonne chance.
la source
J'étais un partisan du style à sortie unique. Mon raisonnement venait principalement de la douleur ...
La sortie unique est plus facile à déboguer.
Compte tenu des techniques et des outils dont nous disposons aujourd'hui, il s'agit d'une position beaucoup moins raisonnable à prendre car les tests unitaires et la journalisation peuvent rendre la sortie unique inutile. Cela dit, lorsque vous avez besoin de regarder le code s'exécuter dans un débogueur, il était beaucoup plus difficile de comprendre et de travailler avec du code contenant plusieurs points de sortie.
Cela devenait particulièrement vrai lorsque vous deviez interjecter des affectations afin d'examiner l'état (remplacé par des expressions de surveillance dans les débogueurs modernes). Il était également trop facile de modifier le flux de contrôle de manière à masquer le problème ou à interrompre complètement l'exécution.
Les méthodes à sortie unique étaient plus faciles à parcourir dans le débogueur et plus faciles à séparer sans rompre la logique.
la source
La réponse est très dépendante du contexte. Si vous créez une interface graphique et que vous avez une fonction qui initialise les API et ouvre les fenêtres au début de votre main, il sera plein d'appels qui peuvent générer des erreurs, dont chacune entraînerait la fermeture de l'instance du programme. Si vous utilisiez des instructions IF imbriquées et indentez votre code pourrait rapidement devenir très biaisé vers la droite. Revenir sur une erreur à chaque étape pourrait être mieux et en fait plus lisible tout en étant tout aussi facile à déboguer avec quelques indicateurs dans le code.
Si, cependant, vous testez différentes conditions et renvoyez des valeurs différentes en fonction des résultats de votre méthode, il peut être préférable d'avoir un seul point de sortie. J'avais l'habitude de travailler sur des scripts de traitement d'images dans MATLAB qui pouvaient devenir très volumineux. Plusieurs points de sortie peuvent rendre le code extrêmement difficile à suivre. Les déclarations Switch étaient beaucoup plus appropriées.
La meilleure chose à faire serait d'apprendre au fur et à mesure. Si vous écrivez du code pour quelque chose, essayez de trouver le code d'autres personnes et voyez comment elles l'implémentent. Décidez quels morceaux vous aimez et quels morceaux vous n'aimez pas.
la source
Si vous sentez que vous avez besoin de plusieurs points de sortie dans une fonction, la fonction est trop volumineuse et en fait trop.
Je recommanderais de lire le chapitre sur les fonctions dans le livre de Robert C. Martin, Clean Code.
Essentiellement, vous devriez essayer d'écrire des fonctions avec 4 lignes de code ou moins.
Quelques notes du blog de Mike Long :
la source