Hallo Call the Doctor!,
normalerweise verwendet man kopf- (while {...}) oder fußgesteuerte Schleifen (do {...} while() ).
Diese können je nach Logik auch eine zusätzliche Abbruchbedingung mittendrin haben, Puristen würden das aber einen heimlichen goto nennen.
Wenn in einem Konstrukt wie
for(;;) {
// do A1
if (condition) break;
// do A2
}
bei dem "do something" mehr passiert als die Vorbereitung der Bedingung, gilt das hingegen als nicht mehr strukturiert.
In schlechten alten COBOL-Tagen habe ich gelernt, dass man dann
VORLAUF
PERFORM UNTIL CONDITION
ACTION
NACHLAUF
END-PERFORM
programmiert. Wobei Vorlauf und Nachlauf die für Init und Re-Init angepasste Form von A1 darstellen.
Dein Konstrukt
for (let x; <condition>; ) {...}
ist, wenn x in der Bedingung nicht genutzt wird, allerdings besser dran, wenn Du es durch while ersetzt. Vor allem, wenn x pro Durchlauf als unverändertlicher Wert bestimmt werden kann. Die let x-Variante im for-Statement hat die Eigenschaft, dass x den Wert aus dem vorigen Durchlauf behält. Das kann Absicht sein oder ein potenzieller Bug. Es hat jedenfalls den Vorteil, dass das Schleifen-x außerhalb der Schleife nicht sichtbar ist.
Bei for (const x of foo) ist der const unproblematisch, weil die for...of Schleife anders agiert als die for (;;)-Schleife. Bei for...of wird pro Durchlauf ein neuer Wert aus dem iterierten Objekt genommen und als const-Wert bereitgestellt. Bei for (;;) gibt es keine automatisierte Datenbeschaffung.
for(A;B;C) { … }entspricht{ A; while(B) {…}}
Nein, es entspricht { A; while(B) {…; C}}. C ist die „Re-Initialisierung“
Aber { A; do { C } while(B); } solltest Du als
for (A; B;) {
C;
}
ausdrücken können, solange A nichts anderes ist als Deklaration und Initialisierung von Variablen. Wie Du schon erkannt hast, ergibt const dort keinen Sinn, und die Lösung hast Du auch gefunden: ziehe das const in den Schleifenrumpf. Das ist vollkommen in Ordnung, finde ich.
Ein for()-Zückerchen für do {} while gibt's nicht. Das ist schon ein Zückerchen für eine while-Schleife mit einem if(!B) break; am Ende.
switch(true) als Ersatz für eine if/else Kette ist eigentlich unnötig. Man tippt wegen der ganzen break-Anweisungen deutlich mehr. Die switch-Anweisung ist als optimierbare Auswahl über einen festen Wert gedacht. Wenn Du die case-Labels berechnest, und sei es als booleschen Wert, ist die Optimierung für die Katz. Aus meiner Sicht wäre das eher syntactic vinegar.
Rolf
sumpsi - posui - obstruxi