Brechen Sie auf Standardfall in Schalter

88

Ich bin ein bisschen verwirrt, wann immer oder wann nicht breaknach dem letzten Fall, oft default.

switch (type) {
    case 'product':

        // Do behavior

        break;
    default:

        // Do default behavior

        break; // Is it considered to be needed?
}

breakMeines switchErachtens besteht der einzige Zweck darin, zu verhindern, dass der Code im Rest des Falls ausgeführt wird.

Wird es dann als logischer angesehen, einen breakLeisten aufgrund von Konsistenz zu haben oder ihn zu überspringen, weil breaküberhaupt keine funktionale Verwendung angewendet wird? Beides ist meiner Meinung nach auf unterschiedliche Weise logisch.

Dies könnte bis zu einem gewissen Grad mit dem Beenden einer .phpDatei mit verglichen werden ?>. Ich ende nie mit, ?>hauptsächlich wegen des Risikos, Leerzeichen auszugeben, aber man könnte argumentieren, dass es die logische Sache wäre, die Datei mit zu beenden.

Robin Castlin
quelle

Antworten:

144

breakwird nach der letzten Alternative technisch nicht benötigt (was wohlgemerkt nicht sein muss default: Es ist vollkommen legal und manchmal sogar nützlich, den defaultZweig an die erste Stelle zu setzen ); ob Ihr Code durch das Ende der switchAnweisung fällt oder breaksam Ende seiner letzten Verzweigung heraus, hat das gleiche Ergebnis.

Aus drei Gründen würde ich dennoch jeden Zweig, einschließlich des letzten, mit einem returnoder beenden break:

  1. Refactorability. Wenn alle Ihre Zweige mit breakoder enden return, können Sie sie neu anordnen, ohne die Bedeutung zu ändern. Dies macht es weniger wahrscheinlich, dass eine solche Neuordnung eine Regression einführt.
  2. Konsistenz und geringste Überraschung. Konsistenz besagt, dass Ihre Zweige konsistent enden sollten, es sei denn, sie haben tatsächlich eine andere Bedeutung. Das Prinzip der geringsten Überraschung schreibt vor, dass ähnliche Dinge ähnlich aussehen sollten. Das Beenden des letzten Zweigs eines switchBlocks, genau wie der vorhergehende, erfüllt beides, was das Lesen und Verstehen erleichtert. Wenn Sie das Explizite weglassen break, wird der letzte Zweig optisch anders sein (was besonders für das schnelle Scannen wichtig ist), und um zu sehen, dass es wirklich nicht anders ist, muss der Leser zum Kern des Lesens einzelner Aussagen absteigen .
  3. Schütze dich. Wenn Sie es sich zur Gewohnheit machen, alle Ihre switchZweige mit einem zu beenden break, wird es nach einer Weile automatisch und Sie werden es seltener versehentlich vergessen, wenn es darauf ankommt. Wenn Sie sich schulen, breakum das Ende jedes Zweigs zu erwarten, können Sie auch fehlende breakAnweisungen erkennen, was sich hervorragend zum Debuggen und zur Fehlerbehebung eignet.
tdammers
quelle
Vielen Dank für Ihren Einblick! Wird auch breakletzter Fall :)
Robin Castlin
7
In C # break(oder einer anderen Steuerflussanweisung, die die beendet case) wird nach der letzten Alternative technisch benötigt.
Dan04
3
@ dan04: ja, guter punkt. C # ist hier eine Ausnahme, und dies liegt wahrscheinlich daran, dass die Sprachentwickler die Probleme mit dem switchDurchbrechen in vorhandenen Sprachen kannten und diese verhindern wollten. Die Regeln, die C # auferlegt, stimmen weitgehend mit den Empfehlungen aus meiner Antwort überein.
tdammers
Über welche Sprache sprichst du konkret? C? C ++? C #? Java? PHP?
Svick
2
Ein guter Compiler würde das Finale breakals NO-OP behandeln, anstatt einen jmpzur nächsten Anweisung zu generieren , richtig?
Nathan Osman
11

In Anbetracht der Mehrdeutigkeit, die bei der Verwendung von switch-casein den meisten Sprachen besteht, würde ichbreak bei der Verwendung vorschlagen, immer eine Anweisung zu verwenden, es sei denn, dies ist ausdrücklich und beabsichtigt unerwünscht .

Dies liegt zum Teil daran, dass jeder caseAnruf gleich aussieht, was meiner Meinung nach die Lesbarkeit verbessern würde. Es bedeutet aber auch, dass sich jemand (auch Sie), caseder zu einem späteren Zeitpunkt ein nach dem letzten einfügen möchte, nicht mit der Überprüfung des vorherigen Blocks befassen muss, was dazu beitragen kann, Fehler beim Hinzufügen von neuem Code zu reduzieren.


quelle
7
Wenn ich möchte, dass ein Fall zum nächsten fällt (und das ist nicht der entartete Fall case foo: case bar: ...), möchte ich ausdrücklich, dass der Fall zustande kommt. Macht es viel klarer.
Donal Fellows
3
Ja wie ein einfacher Kommentar // no breakanstelle vonbreak;
Pacerier
Oder ein [[fallthrough]]Attribut bei C ++.
Ruslan
1

Es ist breaknach dem letzten Fall nicht erforderlich . Ich benutze das Wort " last " (nicht Standard ), weil es nicht notwendig ist, Standard ist der letzte Fall.

switch(x)
{
case 1:
//do stuff
break;

default:
//do default work
break;

case 3:
//do stuff

}

Und wir wissen, a break ist zwischen zwei aufeinanderfolgenden cases notwendig . Manchmal verwende ich if(a!=0)in meinem Code, um die Lesbarkeit zu verbessern, wenn andere auf meinen Code verweisen. Ich kann mich für die Verwendung entscheiden if(a), das wäre eine Frage meiner Wahl

Suvarna Pattayil
quelle
5
Für mich würde das eine "immer Unterbrechung verwenden" bedeuten, nur für den Fall, dass ein Programmierer caseam Ende eine neue hinzufügt, switchohne zu überprüfen, ob die breakexistiert (es wäre die Schuld des Programmierers, aber noch besser sicher - wenn aus irgendeinem Grund weil du in 6 Monaten dieser Programmierer sein könntest-)
SJuan76
@ SJuan76 Ja, ich bin einverstanden, lieber sicher als leid, wenn Sie einen Schutz für zukünftige Fehler behalten möchten, müssen Sie einen am Ende einfügen.
Suvarna Pattayil
1
In Anbetracht dieses Arguments könnten Sie auch argumentieren, immer , am Ende von Arrays zu stehen, falls ein neuer Wert eingefügt wird. Das bricht jedoch einige Codes und sieht im Allgemeinen hässlich aus :)
Robin Castlin
1
@Robin Das Einfügen eines Kommas ist anders. Wenn es nicht vorhanden ist und jemand einem Array einen neuen Wert hinzufügt, wird ein Kompilierungsfehler angezeigt. Es tritt jedoch kein Kompilierungsfehler auf, wenn in der vorherigen case-Anweisung eine Unterbrechung fehlt. Dies könnte daher übersehen werden und zu Laufzeitfehlern führen.
Keith Miller
@RobinCastlin Vorausgesetzt, die Sprache erlaubt es Ihnen, eine ,. Incase defaultwurde entwickelt, um der letzte Fall zu sein. Vielleicht würde die Sprache ein breakdanach als Fehler betrachten. Unter der Annahme , breakwurde als Unterscheidungsmerkmal nur zwischen zwei Fällen erlaubt.
Suvarna Pattayil