Vous pouvez quitter une boucle Comment sortir d'un Y a-t-il une sorte de procedure ...
begin
if .... then
begin
here the code to execute
if (I want to exit = TRUE) then
break or GOTO
here the code not to execute if has exited
end;
here the code to execute
end;
9 Réponses :
En usage général de la pause ou de goto n'est pas considéré comme un style de programmation élégant.
Je vous suggère que vous venez d'inverser votre condition et de dire: ici le code pour exécuter p> extrémité; p> p>
"En usage général de pause ou de goto", je suis fortement en désaccord sur cette déclaration, envisagez une boucle infinie, c'est-à-dire «tandis que le vrai commencez», comment allez-vous briser la boucle et continuer avec la prochaine expression sans utiliser de "pause"? De plus, "Goto's and Labels" sont très puissants s'il est utilisé avec soin.
Continuer et casser - oui. En FSM par exemple. Goto aléatoire dans chaque partie aléatoire du code dangereux. KLater U Déplacez le code dans une autre unité, oubliez de réparer GOTO - et il souffle au hasard.
@Dorinduminica, mon expérience est que Goto va à la maintenabilité et à la lisibilité du code. Il est également vrai que dans certains examens n'est pas autorisé. Bien sûr, il y a toujours le cas dans lequel ils sont nécessaires.
Vous pouvez utiliser des exceptions.
Appelez une avortement dans intérieure si ou en boucle et attrapez EABORT Exception où vous souhaitez continuer P>
type EExitException1 = class(Exception) end;
type EExitException2 = class(Exception) end;
procedure ...
begin
try
if .... then
begin
(* here the code to execute *)
try
if .... then
begin
(* here the nested code to execute *)
if I_want-to-exit then raise EExitException1.Create();
(** ... **)
if I_want-to-exit-far-away then raise EExitException2.Create();
(* here the code not to execute if if-block cancelled *)
end; // if
(* here the code to execute *)
if I_want-to-exit-outer-if-here then raise EExitException2.Create();
(* here the code not to execute *)
except on E: EExitException1 do ; end; // killing the exception
(* here the code to execute after the outer if-block exit *)
end;
(* one more piece of skippable code *)
except on E: EExitException2 do ; end;
(* here the code to execute yet again *)
end;
+1 Pour compenser le -1, non pas que je pense que cela est élégant de quelque manière que ce soit, mais c'est le plus proche d'utiliser Break IMO. Aucune autre réponse ne répond à la question de la puissance qui est "y a-t-il un goto ou une pause?", Et cela semble le plus proche de répondre à sa question. Répondre à sa question avec «Oesté IFS» ne répond pas à sa question.
À mon avis, la mauvaise façon d'utiliser des exceptions. Mieux est d'utiliser Essayer si 123 puis si 456 puis quittez; enfin // code est exécuté de quelque manière que ce soit même pour la fin de sortie;
@John Eh bien, il y a goto, sûrement goto est plus proche de goto qu'une exception
Très intéressant - je n'ai jamais besoin d'utiliser une exception de cette façon ;-)
@DavidHeffernan avait la solution indiquait "Abort", nous ne serions pas aussi concentrés sur l'utilisation de l'exception. Si l'EMTY / SAUF SAIT correspond à la facture de toute façon, alors Abandonnez-vous, alors une solution valide pour sortir un si / alors .. si l'essai / Sauf n'a aucun sens autre que d'utiliser comme goto, alors je suis d'accord. En fait, un essai / enfin serait mieux comme Abande quitterait le bloc et exécuterait enfin
L'élevage d'exceptions est "coûteux" (lorsqu'il est utilisé dans une boucle, cela peut affecter la vitesse d'exécution du programme)
D'accord avec @MJN, de plus, ce code est moins lisible que par exemple essayer..finalement code> .
Il n'est pas seulement moins lisible, il est également plus fragile contre les modifications et la restructuration ultérieures. Il pourrait également devenir moins cher dans des boucles imbriquées profondes, où au lieu de 1% de chances d'élever une exception, vous feriez toujours des tests en ligne de 10 * 10 * 10 * 10. Donc, si cette partie du code est critique de vitesse, oui, goto, allez assembler, allez Spaghetti et presser chaque tac de processeur (et en réalité, Delphi CodeGen est une mauvaise vitesse). Mais si ce code n'est pas critique de vitesse (et la plupart des codes ne sont pas), la lisibilité et la réalité sur l'ancienne maintenabilité ont leur propre valeur.
Le commentaire ci-dessus se compare avec des drapeaux supplémentaires dans chaque si le chemin du chemin. TRY-TRAIT-Enfin, l'approche est mieux à condition que l'itinéraire de sortie unique ait lieu (goto unique à remplacer) et que vous n'utilisez pas beaucoup d'autres blocs.
Comme Piskvor mentionné code> , Utiliser une instruction imbriquée si la déclaration:
procedure Something;
begin
if IWantToEnterHere then
begin
// here the code to execute
if not IWantToExit then
// here the code not to execute if has exited
end;
// here the code to execute
end;
ou: si iwanttostay alors :) N'oubliez pas non plus de "commencements de début" si vous avez plusieurs déclarations
+1 Je suis d'accord avec celui-ci. Bien que Delphi prend en charge le goto et l'étiquette, l'utilisation conduit au code de la Spagheti et à la maintenance cauchemar. Les gotos et les étiquettes me rappellent un langage de bas niveau tel que l'assemblage.
Utilisez la procédure code> en ligne locale code> goto code> phrase;
goto code> phrase diminue la visibilité de votre code. procedure ...
procedue Check; inline;
begin
if .... then
begin
here the code to execute
if (I want to exit = TRUE) then
exit;
here the code not to execute if has exited
end;
end;
begin
Check;
here the code to execute
end;
En fait, j'aime ce style - encore mieux que d'utiliser, essayez enfin des blocs pour contourner la sortie finale.
Avec New Delphi, je pourrais peut-être même utiliser la procédure anonyme, vient de déclarer et instantanément appelé. Bien que moins rapide que la procédure locale, ITO serait plus lisible. Lorsque la fonction complexe appelle beaucoup de procédures locales et que chacune est appelée une seule fois - cela ne fait que lire et comprendre la session de formation de défilement :-(
Je ne suis pas en faveur de l'utilisation de la sortie de cette façon, mais vous l'avez demandé ...
J'aime @mrabat suggéré dans un commentaire à @arich 'la réponse, vous pouvez utiliser le fait qu'un blocage enfin est toujours Exécuté, quelle que soit la sortie et les exceptions, à votre avantage ici: p>
J'ai poussé à l'exception de ce qu'ils permettent aux différentes classes d'exceptions agissent comme des étiquettes cibles différentes. S'il n'y a qu'un seul itinéraire de sauvetage, alors l'approche est enfin meilleure bien sûr. Mais si on aurait besoin de des objectifs de sortie deferent, il aurait alors quelque chose à spécifier la zone d'atterrissage. Et si les drapeaux dans un tel scénario seraient rapidement authentiques si des conditions. BTW, personnellement, je pense que ce code nécessitant une apparence pourrait être semblable à la refactorisation, si elle serait possible.
@ Arioch'the Oui, l'odeur s'élevant de toutes sortes de drapeaux If-drapeaux Enfin ou de toutes sortes de types d'exception spécifiques dans un bloc sauf, indique un besoin presque inévitable de refactoring.
Ceci est couramment mis en œuvre comme ceci:
function testOne: Boolean;
begin
...
end;
function testTwo: Boolean;
begin
...
end;
procedure runTests;
var
bOK: Boolean;
begin
bOK = True;
if bOK then
begin
// Test something
bOK = testOne;
// If we passed, keep going
end;
if bOK then
begin
// Test something else
bOK = testTwo;
// If we passed, keep going
end;
...
end;
+1, cela rend la logique plus claire. J'ai généralement le testone et le testtwo déclaré à l'intérieur des roulements pour le rendre clair où il appartient, tant qu'ils ne peuvent pas être réutilisés ailleurs.
@Lurd +1 pour les procédures imbriquées - une belle encapsulation que je manque cruellement en C ++, etc., en particulier dans les gestionnaires de messages et autres qui ont une grande déclaration de cas et beaucoup de processus d'action appelés par chaque État. Si rien d'autre, je n'ai pas besoin d'ajouter continuellement de nouveaux processus d'action à la classe dans un fichier .h
Après avoir lu les différents commentaires, j'ai décidé de poster une réponse pour montrer comment utiliser le Goto instruction ... BTW, je préfère d'autres méthodes expliquées dans d'autres réponses en évitant sa utilisation:
procedure ...
label
CodeToExecute;
const
iWantToExit = True;
begin
if ... then
begin
ShowMessage('here the code to execute 1');
if iWantToExit then
goto CodeToExecute;
ShowMessage('here the code not to execute if has exited');
end;
CodeToExecute:
ShowMessage('here the code to execute 2');
end;
Vous pouvez utiliser la méthode suivante pour sortir d'un bloc "si" en utilisant "BREAK". Exemple suivant suppose qu'il existe deux boîtes d'édition sur le formulaire. EDIT: clarification, la solution est juste en supposant La question est un teaser cérébral. Ce n'est pas mon moyen recommandé de gérer la situation et je n'utiliserai jamais cela dans mon code. P> p> répéter ... jusqu'à ce que vrai; code> remplace l'habituel commencements ... fin; code>
Ce code fonctionne également et réponses. Donc, je m'empêche de le remettre à zéro neutre. Le problème lui-même n'est pas élégant et toutes les solutions ont leurs inconvénients. Déprimant une certaine réponse sans commenter pourquoi c'est pire que d'autres alternatives ne donnèrent aucune information précieuse.
Code lisible
// si Cond1 puis si Cond2, alors si Cond3, alors - P>
procedure cond1_cond3; begin if not(Cond1) then exit; cond1_work; if not(Cond2) then exit; cond2_work; if not(Cond3) then exit; cond3_work; end; procedure All_Work; begin All_work_1; cond1_cond3; All_work_2; end
Que diriez-vous d'un siblielé si?
si (i __don't __don'd__ ne veut pas quitter), le code ne doit pas exécuter s'il est sorti fin; code>Vous pouvez utiliser «Quitter» pour quitter le formulaire dans une fonction | Procédure
et utilisez des procédures d'anonymocie pour utiliser la sortie sur n'importe quelle déclaration de bloc :-)
Ahhhhhhrrrgrggghhhhhhhhhhhhhhhhh Ce code fait crawler ma peau. Utilisez simplement une autre déclaration si vous ne faites que ce que vous voulez faire, et ne rien faire si vous ne voulez pas le faire.
Apprenez à refactuer votre code afin que vous n'ayez pas de blocs de code géant. Chacun de ces sous-blocs pourrait être transformé en une procédure locale bien nommée, à tout le moins, s'ils n'étaient pas sensiblement mieux transformés en méthodes de certains objets.
Procédures locales, lorsqu'elle est appelée une seule fois, casse la lisibilité. Au lieu de lire et de comprendre que vous venez de faire défiler en permanence d'aller et d'alternance plus visé et trouvés «DAMN! Où est la dernière fois la dernière fois».