Ich schreibe einen Code, der so aussieht:
while(true) {
switch(msg->state) {
case MSGTYPE: // ...
break;
// ... more stuff ...
case DONE:
break; // **HERE, I want to break out of the loop itself**
}
}
Gibt es einen direkten Weg, das zu tun?
Ich weiß, dass ich ein Flag verwenden und aus der Schleife ausbrechen kann, indem ich direkt nach dem Wechsel eine bedingte Pause einlege. Ich möchte nur wissen, ob C ++ bereits ein Konstrukt dafür hat.
goto
ansprechende und manchmal den einzigen sauberen Ausweg. Wenn Sie dazu neigen, Ihren Code in kleine Funktionen zu organisieren, die nur wenige Zeilen lang sind und jeweils eine einzige Aufgabe ausführen, werden Sie nie auf dieses Problem stoßen. (Übrigens wird Ihr Code auch leichter zu lesen sein.):)
Antworten:
Prämisse
Der folgende Code sollte unabhängig von der Sprache oder der gewünschten Funktionalität als schlechte Form angesehen werden:
Unterstützende Argumente
Die
while( true )
Schleife hat eine schlechte Form, weil sie:while(true)
Schleifen verwendet, die nicht unendlich sind, verlieren wir die Fähigkeit zur präzisen Kommunikation, wenn Schleifen tatsächlich keine Abschlussbedingung haben. (Vermutlich ist dies bereits geschehen, daher ist der Punkt umstritten.)Alternative zu "Gehe zu"
Der folgende Code ist eine bessere Form:
Vorteile
Keine Flagge. Nein
goto
. Keine Ausnahmen. Einfach zu wechseln. Leicht zu lesen. Einfach zu reparieren. Zusätzlich der Code:Der zweite Punkt ist wichtig. Ohne zu wissen, wie der Code funktioniert, fallen mir zwei Lösungen ein, wenn mich jemand bittet, die Hauptschleife so zu gestalten, dass andere Threads (oder Prozesse) etwas CPU-Zeit haben:
Option 1
Fügen Sie die Pause bereitwillig ein:
Option 2
Überschreiben ausführen:
Dieser Code ist einfacher (daher leichter zu lesen) als eine Schleife mit einer eingebetteten
switch
. DieisValidState
Methode sollte nur bestimmen, ob die Schleife fortgesetzt werden soll. Das Arbeitspferd der Methode sollte in dieexecute
Methode abstrahiert werden, damit Unterklassen das Standardverhalten überschreiben können (eine schwierige Aufgabe mit einem eingebettetenswitch
undgoto
).Python-Beispiel
Vergleichen Sie die folgende Antwort (auf eine Python-Frage), die auf StackOverflow veröffentlicht wurde:
Gegen:
Dies
while True
führt zu irreführendem und zu komplexem Code.quelle
while(true)
die schädlich sein sollte, erscheint mir bizarr. Es gibt Schleifen, die prüfen, bevor sie ausgeführt werden, es gibt solche, die danach prüfen, und es gibt solche, die in der Mitte prüfen. Da letztere in C und C ++ kein syntaktisches Konstrukt haben, müssen Siewhile(true)
oder verwendenfor(;;)
. Wenn Sie dies für falsch halten, haben Sie noch nicht genug über die verschiedenen Arten von Schleifen nachgedacht.while(true) {string line; std::getline(is,line); if(!is) break; lines.push_back(line);}
Natürlich könnte ich dies in eine vorkonditionierte Schleife umwandeln (unter Verwendungstd::getline
der Schleifenbedingung), aber dies hat seine eigenen Nachteile (line
müsste eine Variable außerhalb des Bereichs der Schleife sein). Und wenn ich das tun würde, müsste ich fragen: Warum haben wir überhaupt drei Schleifen? Wir könnten immer alles in eine vorkonditionierte Schleife verwandeln. Verwenden Sie, was am besten passt. Wenn eswhile(true)
passt, dann benutze es.Sie können verwenden
goto
.quelle
goto
. Das OP klar erwähnt ohne Verwendung von Flags . Können Sie angesichts der Einschränkungen des OP einen besseren Weg vorschlagen? :)Eine alternative Lösung besteht darin, das Schlüsselwort
continue
in Kombination mit folgendenbreak
Elementen zu verwenden:Verwenden Sie die
continue
Anweisung, um jede Fallbezeichnung zu beenden, an der die Schleife fortgesetzt werden soll, und verwenden Sie diebreak
Anweisung, um Fallbezeichnungen zu beenden, die die Schleife beenden sollen.Natürlich funktioniert diese Lösung nur, wenn nach der switch-Anweisung kein zusätzlicher Code ausgeführt werden muss.
quelle
:(
:(
Sonst eine sehr saubere Implementierung.Ein ordentlicher Weg, dies zu tun, wäre, dies in eine Funktion zu setzen:
Optional (aber "schlechte Praktiken"): Wie bereits vorgeschlagen, können Sie ein goto verwenden oder eine Ausnahme in den Switch werfen.
quelle
AFAIK gibt es in C ++ kein "Double Break" oder ähnliches Konstrukt. Das nächste wäre ein
goto
- das zwar eine schlechte Konnotation zu seinem Namen hat, aber aus einem bestimmten Grund in der Sprache existiert - solange es sorgfältig und sparsam verwendet wird, ist es eine praktikable Option.quelle
Sie können Ihren Schalter wie folgt in eine separate Funktion umwandeln:
quelle
Auch wenn Sie goto nicht mögen, verwenden Sie keine Ausnahme, um eine Schleife zu verlassen. Das folgende Beispiel zeigt, wie hässlich es sein könnte:
Ich würde
goto
wie in dieser Antwort verwenden. In diesem Fallgoto
wird der Code klarer als bei jeder anderen Option. Ich hoffe, dass diese Frage hilfreich sein wird.Aber ich denke, dass die Verwendung
goto
hier aufgrund der Zeichenfolge die einzige Option istwhile(true)
. Sie sollten ein Refactoring Ihrer Schleife in Betracht ziehen. Ich würde die folgende Lösung annehmen:Oder sogar das Folgende:
quelle
goto
, verwenden Sie keine Ausnahme, um eine Schleife zu verlassen:"?In diesem Fall gibt es kein C ++ - Konstrukt, um aus der Schleife auszubrechen.
Verwenden Sie entweder ein Flag, um die Schleife zu unterbrechen, oder extrahieren Sie (falls zutreffend) Ihren Code in eine Funktion und verwenden Sie
return
.quelle
Sie könnten möglicherweise goto verwenden, aber ich würde es vorziehen, ein Flag zu setzen, das die Schleife stoppt. Dann aus dem Schalter ausbrechen.
quelle
Warum nicht einfach den Zustand in Ihrer while-Schleife beheben und das Problem verschwinden lassen?
quelle
Nein, C ++ hat hierfür kein Konstrukt, da das Schlüsselwort "break" bereits für das Verlassen des Switch-Blocks reserviert ist. Alternativ könnte ein do..while () mit einem Exit-Flag ausreichen.
quelle
Meiner Ansicht nach;
quelle
Der einfachste Weg, dies zu tun, besteht darin, vor dem SWITCH eine einfache IF zu setzen und diese IF Ihre Bedingung für das Verlassen der Schleife zu testen .......... so einfach wie möglich
quelle
Das
break
Schlüsselwort in C ++ beendet nur die am meisten verschachtelte einschließende Iteration oderswitch
Anweisung. Sie konnten also nichtwhile (true)
direkt innerhalb derswitch
Anweisung aus der Schleife ausbrechen . Sie können jedoch den folgenden Code verwenden, der meiner Meinung nach ein hervorragendes Muster für diese Art von Problem darstellt:Wenn Sie etwas tun müssen, wenn es
msg->state
gleich istDONE
(z. B. eine Bereinigungsroutine ausführen), platzieren Sie diesen Code unmittelbar nach derfor
Schleife. dh wenn Sie derzeit haben:Verwenden Sie stattdessen:
quelle
Es wundert mich, wie einfach dies angesichts der Tiefe der Erklärungen ist ... Hier ist alles, was Sie brauchen ...
LOL !! Ja wirklich! Das ist alles was du brauchst! Eine zusätzliche Variable!
quelle
quelle
Ich habe das gleiche Problem und mit einer Flagge gelöst.
quelle
Wenn ich mich gut an die C ++ - Syntax erinnere, können Sie
break
Anweisungen wie für eine Bezeichnung hinzufügengoto
. Was Sie wollen, lässt sich also leicht schreiben:quelle
quelle