Prämisse
Der folgende Code sollte unabhängig von der Sprache oder der gewünschten Funktionalität als schlechte Form angesehen werden:
while( true ) {
}
Unterstützende Argumente
Die while( true )
Schleife hat eine schlechte Form, weil sie:
- Bricht den impliziten Vertrag einer while-Schleife.
- Die while-Schleifendeklaration sollte explizit die einzige Exit-Bedingung angeben.
- Impliziert, dass es für immer Schleifen.
- Code innerhalb der Schleife muss gelesen werden, um die Abschlussklausel zu verstehen.
- Schleifen, die sich für immer wiederholen, verhindern, dass der Benutzer das Programm innerhalb des Programms beendet.
- Ist ineffizient.
- Es gibt mehrere Bedingungen für die Beendigung von Schleifen, einschließlich der Überprüfung auf "true".
- Ist anfällig für Fehler.
- Es kann nicht einfach bestimmt werden, wo Code abgelegt werden soll, der immer für jede Iteration ausgeführt wird.
- Führt zu unnötig komplexem Code.
- Automatische Quellcode-Analyse.
- Um Fehler zu finden, die Komplexität der Programme zu analysieren, Sicherheitsüberprüfungen durchzuführen oder automatisch ein anderes Verhalten des Quellcodes ohne Codeausführung abzuleiten, können Algorithmen durch Angabe der anfänglichen Unterbrechungsbedingungen nützliche Invarianten bestimmen und so die Metriken für die automatische Quellcode-Analyse verbessern.
- Endlosschleifen.
- Wenn jeder immer
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:
while( isValidState() ) {
execute();
}
bool isValidState() {
return msg->state != DONE;
}
Vorteile
Keine Flagge. Nein goto
. Keine Ausnahmen. Einfach zu wechseln. Leicht zu lesen. Einfach zu reparieren. Zusätzlich der Code:
- Isoliert das Wissen über die Arbeitslast der Schleife von der Schleife selbst.
- Ermöglicht es jemandem, der den Code verwaltet, die Funktionalität einfach zu erweitern.
- Ermöglicht die Zuweisung mehrerer Abschlussbedingungen an einem Ort.
- Trennt die Abschlussklausel vom auszuführenden Code.
- Ist sicherer für Kernkraftwerke. ;-);
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:
while( isValidState() ) {
execute();
sleep();
}
Option 2
Überschreiben ausführen:
void execute() {
super->execute();
sleep();
}
Dieser Code ist einfacher (daher leichter zu lesen) als eine Schleife mit einer eingebetteten switch
. Die isValidState
Methode sollte nur bestimmen, ob die Schleife fortgesetzt werden soll. Das Arbeitspferd der Methode sollte in die execute
Methode abstrahiert werden, damit Unterklassen das Standardverhalten überschreiben können (eine schwierige Aufgabe mit einem eingebetteten switch
und goto
).
Python-Beispiel
Vergleichen Sie die folgende Antwort (auf eine Python-Frage), die auf StackOverflow veröffentlicht wurde:
- Schleife für immer.
- Bitten Sie den Benutzer, seine Wahl einzugeben.
- Wenn die Benutzereingabe "Neustart" lautet, setzen Sie die Schleife für immer fort.
- Andernfalls hören Sie für immer auf, eine Schleife zu erstellen.
- Ende.
Code
while True:
choice = raw_input('What do you want? ')
if choice == 'restart':
continue
else:
break
print 'Break!'
Gegen:
- Initialisieren Sie die Auswahl des Benutzers.
- Schleife, während der Benutzer das Wort "Neustart" auswählt.
- Bitten Sie den Benutzer, seine Wahl einzugeben.
- Ende.
Code
choice = 'restart';
while choice == 'restart':
choice = raw_input('What do you want? ')
print 'Break!'
Dies while True
führt zu irreführendem und zu komplexem Code.