Ist mit einem 'goto' - Anweisung schlecht?
Nachdem ich einige reseach, wie zu brechen, die durch eine sekundäre Schleife
while (true) { //Main Loop
for (int I = 0; I < 15; I++) { //Secondary loop
//Do Something
break; //Break main loop?
}
}
meisten Menschen empfohlen, rufen Sie die 'gehe zu' - Funktion
Suchen, wie im folgenden Beispiel:
while (true) { //Main Loop
for (int I = 0; I < 15; I++) { //Secondary Loop
//Do Something
goto ContinueOn; //Breaks the main loop
}
}
ContinueOn:
Jedoch; ich habe oft gehört, dass die 'goto' - Anweisung ist eine schlechte Praxis. Das Bild unten ist perfekt illustriert meinen Punkt:
So
- Wie schlimm ist die goto-Anweisung wirklich, und warum?
- gibt es eine effektivere Art und Weise zu brechen, die die main-loop als mit der 'goto' - Anweisung?
- Es ist nicht wirklich schlecht, seine nur, dass über 99% der Zeit, die andere loop-Konstrukte verwendet werden können, um zu schreiben, sauberer und klarer, in der Regel besseren code.
- Ich nehme an, Sie meinte nur
while(true)
eher alsdo while(true)
? - So etwas wie sein: loopVal=true while (loopVal){ for(){ if (){ loopVal=false; break; } } }
Is there a more effective way to break the main loop than using the 'goto' statement?
Wie ist das nicht eine berechtigte Frage?- Das springen sieht sauberer aus, imo. Aber dann wieder, ich kann nicht machen, eine Antwort cos wird Es downvoted.
- Candi, contThis macht das Gegenteil von break; Anstelle der Beendigung der Schleife sofort Schleifen wieder, überspringen Sie den rest des Codes.inue überspringt und weiter mit der Schleife meinst du Pause hier ist ein guter link, um zu erklären den Unterschied cplus.about.com/od/learningc/ss/clessonfive_3.htm
- Das scheint mir ein durchaus vernünftiger Weg, um Büste aus einer tief verschachtelten Schleife. SPRINGEN bekommt seine "große satan" Ruf aus der Nutzung mit den Zeilennummern und den unnötigen Gebrauch in Fällen, wo etwas benötigt, um in eine Funktion. In JS haben wir beschriftet-Schleifen, die machen es einfach ausbrechen aus verschachtelten Schleifen auf jeder Ebene. Ich sehe nichts falsch mit diesem, obwohl, ich würde einen Kommentar hinzufügen Erläuterung, um zu vermeiden, reflexartige Hysterie von devs, die nicht wirklich verstehen, die Abneigung zu springen. Solange Sie die Einstellung nicht SPRINGEN, aber irgendwo am Ende einer Schleife oder einer äußeren Schleife gibt es kein Geruch IMO.
- Wenn wir gehen, um die Debatte darüber, ob oder nicht SPRINGEN, ist immer noch eine schlechte Praxis, allgemein, dann ist dies ein Duplikat ist. Ansonsten halten die Diskussion lokale, um seinen code.
- Wenn Sie schreiben, eine Antwort, goto ist vollkommen in Ordnung und Sie können einen Fall basierend auf der praktischen Nützlichkeit im konkreten Szenario, wie von der OP, Sie werden nicht get downvoted. Wenn Ihr einziger Grund ist, weil es sieht cleaner,..Sie könnten Recht haben.
- Ich habe so getan, jetzt aber habe ich das Gefühl, es ist alles vergebliche Mühe. Im Wettbewerb gegen Jon Skeet und alle, in einer Sprache, die ich bin nicht vertraut mit.
- Ich würde es nicht als Wettbewerb. Sie haben einen gültigen Punkt in Ihrem Beitrag, und John machte ein Gültiger Punkt in seinem post. Ich persönlich kann sich mit John ' s Ansatz, aber das hat nichts zu tun mit seinen Punkten, es ist mehr mit der Tatsache zu tun, dass ich früher gehe in VB6 (glücklich und richtig), aber in C# hatte nie die Notwendigkeit, due to return, break, Erträge, etc... das bedeutet nicht, Dass springen ist falsch. Ich finde auch, dass beim schreiben von testbarem code, den Sie schreiben Methoden, die eine konzentrierte Einheit von Arbeit, die Sie einfach unit-Tests. Nebenwirkungen von goto in manchen Fällen schwer zu unit-test.
- ja, ich beziehe mich auf Fälle, in denen die gesamte nested-loop-Konstrukt ist eine Einheit, ich würde kein problem haben mit der Trennung wirklich trennen Sie Einheiten in Ihre eigenen Funktionen. Es würde keinen Sinn machen unit-Tests meine
Inner
Funktion ohne die übergeordnete Schleife zum Beispiel. - gehe in ein switch case ist eine große Hilfe beim Umgang mit Fällen, die wiederholt den gleichen code ein : haben Sie ein label in einem switch-case-Anweisung, dann setzen Sie springen, anstatt eine Pause in den Fällen, in Abschnitte, die einige gemeinsame Logik. Es klingt nicht so hässlich wie das, plus das label Geltungsbereich beschränkt sich auf die switch case.
Du musst angemeldet sein, um einen Kommentar abzugeben.
EDIT:
Hängt es von der genauen situation. Ich kann mich nicht erinnern, jedes mal wo ich es gemacht, den code lesbarer als refactoring. Es hängt auch von Ihrer persönlichen Sicht auf die Lesbarkeit - einige Leute mögen es mehr als andere, wie aus den anderen Antworten. (Als ein Punkt des Interesses, es ist weit verbreitet in generiert code - all das async/await-code in C# 5 basiert auf effektiv eine Menge von gotos).
Das problem ist, dass Situationen, in denen
goto
eher neigen zu sein, die Art von Situationen, wo refactoring aids-Dinge, die ohnehin - in der Erwägung, dassgoto
- sticks mit einer Lösung, die schwieriger zu Folgen, als der code wird komplizierter.Absolut. Extrahieren Sie Ihre Methode in eine separate Funktion:
Ich in der Regel bevorzugen, tun dies über die Einführung eines zusätzlichen lokalen Variablen zu verfolgen "habe ich fertig" - obwohl, das wird funktionieren, natürlich.
goto
Aussagen - eine Angst, die ist ein Relikt aus den 1970er Jahren.goto
ist eine weitere einfache Möglichkeit zum Ausbruch aus dem main-loop, und ich sehe nicht ein Nachteil für die VerwendungWerde ich Stimme nicht mit all den anderen Antworten hier. Der code, den Sie präsentieren mit
goto
hat nichts falsch mit ihm. Es ist ein Grund C# hat einegoto
- Anweisung, und es ist genau für diese Arten von Szenarien, die Sie beschreiben.goto
hat einfach eine negative Stigmatisierung, weil in den 1970er Jahren und vor Menschen zu schreiben, wäre schrecklich, vollständig wartbaren code, wo Ablaufsteuerung sprang ganz über dem Platz, weil dergoto
. C#'sgoto
gar nicht erlauben, den übergang zwischen den Methoden! Aber trotzdem ist da diese irrationale stigma gegen Sie.Meiner Meinung nach, gibt es absolut nichts falsch mit der Verwendung einer "modernen"
goto
zu brechen, aus einer inneren Schleife. Die "alternativen" Menschen bieten immer am Ende wird komplizierter und schwerer zu Lesen.Methoden sind im Allgemeinen soll wiederverwendbare. Eine ganze eigene Methode für den inneren Teil einer Schleife, die immer nur mitgehen, die einem Standort, und wo die Implementierung der Methode können am Ende wird an einer entfernten Stelle im Quellcode, ist nicht eine Verbesserung.
Diese Art von dumme übung zu vermeiden
goto
ist im Grunde das äquivalent der politischen Korrektheit, aber in der Welt des Programmierens.goto
in C#. Für eine Sprache wie C oder C++, wo Sie können diese Arten von verrückten Dinge, die mitgoto
ich Zustimmen, es ist gefährlich. In C# ist es vorhanden weitgehend für den Zweck ausbrechen aus verschachtelten Schleifen.Ist es wirklich schlecht für die normalen Gründe. Es prefectly in Ordnung, wenn die Emulation beschriftet Schleifen in Sprachen, die diese nicht unterstützen.
Ersetzen Sie es mit Funktionen wird in vielen Fällen scatter-Logik, die wirklich gelesen werden sollte, da die gleiche Einheit. Dies macht es schwieriger zu Lesen.
Niemand mag es, Folgen Sie den Spuren von Funktionen, die nicht wirklich etwas, bis am Ende der Reise, wenn Sie etwas vergessen
wo aus Sie gestartet sind.
Ersetzen Sie es mit booleans und eine Reihe weiterer ifs und Pausen ist einfach wirklich klobig und macht es schwieriger zu Folgen, wahren Absichten, wie jedes Geräusch.
In java (und javascript), dies ist durchaus akzeptabel (mit Schlaufen):
In C#, es sieht aus wie eine sehr enge Entsprechung nicht:
Weil das Wort
goto
, das hat einen psychologischen Effekt, dass Menschen ablegen, die alle Ihren gesunden Menschenverstand und machen Sie link xkcd unabhängig vom Kontext.In einigen Fällen gibt es nicht, weshalb die anderen Sprachen beschriftet loops und C# bietet
goto
. Beachten Sie, dass Ihr Beispiel ist zu einfach und es machtdie Workarounds nicht zu schlecht aussieht, weil Sie sind zugeschnitten auf die Beispiel. In der Tat, ich könnte genauso gut vorschlagen, diese:
Wie wäre es damit:
Tut dies immer noch gut Aussehen auf Sie:
goto
zureturn
undbreak
. Blick auf die möglichen miss-verwendet vongoto
und unerwünschten Nebenwirkungen, wenn verglichen mit der möglichen Anzahl von miss-verwendet, die man machen kann mitreturn
oderbreak
ich kann sehen, warumgoto
ist nicht ein Favorit. Aber, dass ist nicht, weil es unbedingt etwas falsch mitgoto
aber, dass es zu viel miss-verwenden. Ich denke, obwohl dein post ist ein sehr Gültiger Punkt.Benutze ich manchmal "springen" und ich fand es gut aussieht, wie das Beispiel oben;
Ich weiß, Sie können tun, die gleiche Sache, die rekursiv, aber who cares, es funktioniert einfach und ich verwenden.
Stimme ich mit der Mehrheit der Antworten darüber, wie schlecht ist springen.
Meine sugestion zu vermeiden, springen ist etwas wie dieses:
Einem Kollegen von mir (die 15 Jahre+ in der firmware-Programmierung) und ich gehe die ganze Zeit. Wir verwenden allerdings nur für den Umgang mit Ausnahmen!!!! Zum Beispiel:
Meines Wissens nach ist dies der beste Weg, um behandeln Sie Ausnahmen in C. ich glaube, ich arbeitet für C# zu. Auch bin ich nicht der einzige, der so denkt: Beispiele guter gotos in C oder C++
Ich persönlich halte goto als "goto" führt in die Hölle"...und in vieler Hinsicht ist dies wahr, wie es kann dazu führen, sehr wartbaren code und wirklich schlechte Praktiken.
That being said, es ist immer noch umgesetzt werden für einen Grund, und wenn verwendet, sollte es sparsam verwendet werden, wenn KEINE andere Lösung verfügbar ist. OO-Sprachen bieten sich auch nicht wirklich brauchen (viel).
Das einzige mal, das ich JEMALS sehen, es verwendet in diesen Tagen ist in der Verschleierung...ein goot Beispiel für die Verwendung von goto zu erstellen, die code aus der Hölle, damit die Leute abgeschreckt werden versuchen, es zu verstehen!
Einige Sprachen angewiesen auf entsprechende keywords. Zum Beispiel in x86-assember haben Sie keywords wie JMP (Sprung), JE (Jump if Equal) und JZ (Jump if Zero). Diese sind erforderlich, Häufig in Assembler, da gibt es kein OO auf dieser Ebene, und es gibt paar andere Methoden zum bewegen in einer Anwendung.
AFAIK...bleiben Sie Weg von es, es sei denn ABSOLUT NOTWENDIG.
Hinzufügen zu den anderen Antworten hier, abgesehen von ausbrechen aus verschachtelten Schleifen, die eine ordentliche Nutzung von goto ist einfach und sauber, state-machines:
Dies ist eine ziemlich saubere und gut lesbare Art und Weise zu tun, Zustandsautomaten, und auf der Oberseite ist es performance freundlich kostenlos!
Während Sie dies tun könnte, ohne zu springen, wäre es eigentlich nur Ihr code weniger lesbar. Nicht vermeiden, goto, nur ein bisschen denken, bevor Sie es verwenden.