Warum setzt der Compiler nicht automatisch break-Anweisungen nach jedem Codeblock im Switch? Ist es aus historischen Gründen? Wann sollen mehrere Codeblöcke ausgeführt werden?
93
Warum setzt der Compiler nicht automatisch break-Anweisungen nach jedem Codeblock im Switch? Ist es aus historischen Gründen? Wann sollen mehrere Codeblöcke ausgeführt werden?
break
.Antworten:
Manchmal ist es hilfreich, mehrere Fälle mit demselben Codeblock zu verknüpfen, z
usw. Nur ein Beispiel.
Nach meiner Erfahrung ist es normalerweise ein schlechter Stil, "durchzufallen" und mehrere Codeblöcke für einen Fall ausführen zu lassen, aber in einigen Situationen kann es Verwendungen dafür geben.
quelle
// Intentional fallthrough.
wenn Sie eine Pause auslassen. Es ist meiner Meinung nach weniger ein schlechter Stil als "leicht, eine Pause versehentlich zu vergessen". PS Natürlich nicht in einfachen Fällen wie in der Antwort selbst.case
s auf diese Weise gestapelt werden. Wenn sich dazwischen Code befindet, ist der Kommentar wahrscheinlich verdient.case
, etwa so:case 'A','B','C': doSomething(); case 'D','E': doSomethingElse();
, ohne eine Pause zwischen den Fällen zu benötigen. Pascal könnte dies tun: "Die case-Anweisung vergleicht den Wert des Ordnungsausdrucks mit jedem Selektor, der eine Konstante, ein Unterbereich oder eine durch Kommas getrennte Liste sein kann." ( wiki.freepascal.org/Case )Historisch gesehen liegt dies daran, dass im
case
Wesentlichen ein definiert wurdelabel
, der auch als Zielpunkt einesgoto
Anrufs bezeichnet wird. Die switch-Anweisung und die zugehörigen Fälle stellen wirklich nur einen Mehrwegezweig mit mehreren potenziellen Eintrittspunkten in einen Codestrom dar.Trotzdem wurde fast unendlich oft festgestellt, dass dies
break
fast immer das Standardverhalten ist, das Sie am Ende eines jeden Falles lieber hätten.quelle
Java kommt von C und das ist die Syntax von C.
Es gibt Zeiten, in denen mehrere case-Anweisungen nur einen Ausführungspfad haben sollen. Unten sehen Sie ein Beispiel, das Ihnen sagt, wie viele Tage in einem Monat.
quelle
Ich denke es ist ein Fehler. Als Sprachkonstrukt ist es genauso einfach
break
wie das Standardkonstrukt und hat stattdessen einfallthrough
Schlüsselwort. Der größte Teil des Codes, den ich geschrieben und gelesen habe, hat nach jedem Fall eine Pause.quelle
continue <case name>
welche explizit angeben kann, mit welcher case-Anweisung fortgefahren werden soll.case
innerhalb des Stroms zugelassen wirdswitch
, wird dies einfach zu einemgoto
. ;-)Sie können alle möglichen interessanten Dinge mit Fallfall tun.
Angenommen, Sie möchten eine bestimmte Aktion für alle Fälle ausführen, aber in einem bestimmten Fall möchten Sie diese Aktion plus etwas anderes ausführen. Die Verwendung einer switch-Anweisung mit Fall-Through würde dies recht einfach machen.
Natürlich ist es leicht, die
break
Aussage am Ende eines Falles zu vergessen und unerwartetes Verhalten zu verursachen. Gute Compiler werden Sie warnen, wenn Sie die break-Anweisung weglassen.quelle
Abgesehen von dem guten Wunsch, den identischen Block für mehrere Fälle verwenden zu können (die speziell behandelt werden könnten) ...
Es dient hauptsächlich der Kompatibilität mit C und ist wohl ein uralter Hack aus alten Zeiten, als
goto
Schlüsselwörter die Erde durchstreiften. Es tut einige erstaunliche Dinge ermöglichen, natürlich, wie Duff Gerät , aber ob das ist ein Punkt zu seinen Gunsten oder gegen ist ... argumentative am besten.quelle
Das
break
nach dem Einschaltencase
s wird verwendet , um den Durchfall in den Switch - Anweisungen zu vermeiden. Interessanterweise kann dies jetzt durch die neu gebildeten Switch-Labels erreicht werden, die über JEP-325 implementiert wurden .Mit diesen Änderungen kann das
break
mit jedem Schaltercase
vermieden werden, wie weiter gezeigt wird:Bei Ausführung des obigen Codes mit JDK-12 könnte die Vergleichsausgabe als angesehen werden
und
und natürlich die Sache unverändert
quelle
Sie müssen den Code also nicht wiederholen, wenn Sie mehrere Fälle benötigen, um dasselbe zu tun:
Oder Sie können Dinge tun wie:
In einer Kaskadenart.
Wirklich fehleranfällig, wenn Sie mich fragen.
quelle
do this
unddo that
dafür aber nurdo that
dafür?Was die historischen Aufzeichnungen betrifft, hat Tony Hoare die Fallbeschreibung in den 1960er Jahren während der Revolution der "strukturierten Programmierung" erfunden. Tonys case-Anweisung unterstützte mehrere Labels pro Fall und das automatische Beenden ohne stinkende
break
Anweisungen. Die Anforderung für eine explizitebreak
war etwas, das aus der BCPL / B / C-Linie kam. Dennis Ritchie schreibt (in ACM HOPL-II):Ich konnte keine historischen Schriften über BCPL finden, aber Ritchies Kommentar legt nahe, dass dies
break
mehr oder weniger ein historischer Unfall war. BCPL hat das Problem später behoben, aber vielleicht waren Ritchie und Thompson zu beschäftigt, Unix zu erfinden, um sich mit einem solchen Detail zu beschäftigen :-)quelle
break
die Ausführung von "mehreren Codeblöcken" ermöglicht, und befasst sich mehr mit der Motivation dieser Entwurfswahl. Andere erwähnten das bekannte Erbe von C bis Java, und diese Antwort trieb die Forschung noch weiter in die Zeit vor C. Ich wünschte, wir hätten dieses (wenn auch sehr primitive) Muster von Anfang an.Java leitet sich von C ab, dessen Erbe eine als Duff's Device bekannte Technik umfasst . Es ist eine Optimierung, die auf der Tatsache beruht, dass die Kontrolle von einem Fall zum nächsten fällt, wenn keine
break;
Aussage vorliegt. Zu der Zeit, als C standardisiert wurde, gab es eine Menge solchen Codes "in the wild", und es wäre kontraproduktiv gewesen, die Sprache zu ändern, um solche Konstruktionen zu brechen.quelle
Wie die Leute bereits sagten, ist es ein Durchfallen und es ist kein Fehler, es ist eine Funktion. Wenn Sie zu viele
break
Anweisungen stören, können Sie sie leicht entfernen, indem Sie stattdessenreturn
Anweisungen verwenden. Dies ist eigentlich eine gute Vorgehensweise, da Ihre Methoden so klein wie möglich sein sollten (aus Gründen der Lesbarkeit und Wartbarkeit), sodass eineswitch
Anweisung bereits groß genug für eine Methode ist. Daher sollte eine gute Methode nichts anderes enthalten ein Beispiel:Die Ausführung druckt:
wie erwartet.
quelle
Wenn der Compiler keine automatische Unterbrechung hinzufügt, können Sie einen Schalter / Fall verwenden, um auf Bedingungen zu testen, z. B.
1 <= a <= 3
indem Sie die Unterbrechungsanweisung von 1 und 2 entfernen.quelle
weil es Situationen gibt, in denen Sie beispielsweise durch den ersten Block fließen möchten, um zu vermeiden, dass derselbe Code in mehrere Blöcke geschrieben wird, diese aber dennoch für die mroe-Steuerung aufgeteilt werden können. Es gibt auch eine Menge anderer Gründe.
quelle
Es ist eine alte Frage, aber tatsächlich bin ich heute auf die Verwendung des Falls ohne Unterbrechung gestoßen. Die Nichtverwendung von break ist tatsächlich sehr nützlich, wenn Sie verschiedene Funktionen nacheinander kombinieren müssen.
Beispiel: Verwendung von http-Antwortcodes zur Authentifizierung des Benutzers mit einem Zeit-Token
Server-Antwortcode 401 - Token ist veraltet -> Token neu
generieren und Benutzer anmelden. Server-Antwortcode 200 - Token ist in Ordnung -> Benutzer anmelden.
in case Aussagen:
Auf diese Weise müssen Sie die Anmeldebenutzerfunktion für die 401-Antwort nicht aufrufen, da die Laufzeit bei der Neuerstellung des Tokens in den Fall 200 springt.
quelle
Sie können leicht andere Arten von Zahlen, Monaten und Zählungen trennen.
Dies ist besser als in diesem Fall;
quelle
Ich arbeite jetzt an einem Projekt, das ich
break
in meiner switch-Anweisung benötige , sonst funktioniert der Code nicht. Nehmen Sie mich mit und ich werde Ihnen ein gutes Beispiel dafür geben, warum Sie esbreak
in Ihrer switch-Anweisung benötigen .Stellen Sie sich vor, Sie haben drei Zustände, einen, der darauf wartet, dass der Benutzer eine Zahl eingibt, den zweiten, um sie zu berechnen, und den dritten, um die Summe zu drucken.
In diesem Fall haben Sie:
Wenn Sie sich die Zustände ansehen , möchten Sie, dass die Reihenfolge der Genauigkeit bei Zustand1 , dann bei Zustand3 und schließlich bei Zustand2 beginnt . Andernfalls drucken wir nur Benutzereingaben, ohne die Summe zu berechnen. Um es noch einmal zu verdeutlichen, warten wir, bis der Benutzer einen Wert eingibt, berechnen dann die Summe und drucken die Summe aus.
Hier ist ein Beispielcode:
Wenn wir nicht verwenden
break
, wird es in dieser Reihenfolge ausgeführt, state1 , state2 und state3 . Mit verwendenbreak
wir dieses Szenario jedoch und können in der richtigen Prozedur bestellen, die mit state1, dann state3 und nicht zuletzt state2 beginnt.quelle
Genau, weil Sie mit einer cleveren Platzierung Blöcke in Kaskade ausführen können.
quelle