Ist es eine schlechte Praxis, eine if-Anweisung ohne geschweifte Klammern zu verwenden? [geschlossen]

130

Ich habe Code wie diesen gesehen:

if(statement)
    do this;
else
    do this;

Ich denke jedoch, dass dies besser lesbar ist:

if(statement){
    do this;
}else{
    do this;
}

Da beide Methoden funktionieren, ist dies einfach eine Frage der Präferenz, die verwendet werden soll, oder wird ein Weg dem anderen empfohlen?

Jerebear
quelle
Meiner Meinung nach ist es schlecht, weil Sie sich auf Leerzeichen verlassen, die fast nie vollständig konsistent sind. Es entgleist dem Gedankengang des Lesers, wenn er sich um solche Dinge sorgen muss.
Sridhar Sarnobat

Antworten:

212

Das Problem mit der ersten Version besteht darin, dass Ihr Code auf unerwartete und amüsante Weise unterbrochen wird, wenn Sie zurückgehen und den if- oder else-Klauseln eine zweite Anweisung hinzufügen, ohne daran zu denken, die geschweiften Klammern hinzuzufügen.

In Bezug auf die Wartbarkeit ist es immer klüger, die zweite Form zu verwenden.

EDIT: Ned weist in den Kommentaren darauf hin, aber ich denke, es lohnt sich auch, hier darauf zu verlinken. Dies ist nicht nur ein hypothetischer Bullshit aus dem Elfenbeinturm: https://www.imperialviolet.org/2014/02/22/applebug.html

Clee
quelle
17
Und Sie sollten immer Code für die Wartbarkeit codieren. Schließlich bin ich mir ziemlich sicher, dass es dem Compiler egal ist, welches Formular Sie verwenden. Ihre Mitarbeiter können jedoch pist sein, wenn Sie einen Fehler aufgrund eines dummen Fehlers in geschweiften Klammern einführen.
Esteban Araya
12
Oder Sie könnten eine Sprache verwenden, die keine Klammern für Codeblöcke verwendet ...
Tor Valamo
10
@ lins314159 - Nein, ich meine wie Python. Weil ich in dieser Hinsicht chauvinistisch bin.
Tor Valamo
17
Weitere Beweisfehler können (und können) passieren: imperialviolet.org/2014/02/22/applebug.html
Ned
8
Die Behauptung, der SSL-Fehler sei ein Argument für geschweifte Klammern, ist unaufrichtig. Es ist nicht so, dass der Entwickler schreiben wollte, if (…) { goto L; goto L; }sondern die geschweiften Klammern vergessen hat. Es ist rein zufällig, dass `` if (…) {goto L; gehe zu L; } `ist zufällig kein Sicherheitsfehler, da es sich immer noch um einen Fehler handelt (nur keinen mit Sicherheitsfolgen). In einem anderen Beispiel könnten die Dinge in die entgegengesetzte Richtung gehen und der spannerlose Code könnte versehentlich sicher sein. In einem dritten Beispiel wäre der Code ohne Klammern anfangs fehlerfrei und der Entwickler würde beim Hinzufügen der Klammern einen Tippfehler einführen.
Pascal Cuoq
112

Ein Problem beim Weglassen von Anweisungsblöcken ist die else-Ambiguität. Das heißt, C-inspirierte Sprachen ignorieren Einrückungen und haben daher keine Möglichkeit, dies zu trennen:

if(one)
    if(two)
        foo();
    else
        bar();

Davon:

if(one)
    if(two)
        foo();
else
    bar();
Doynax
quelle
8
Dies ist ein weitaus schwerwiegenderes Problem als das in der oberen Antwort erwähnte (Hinzufügen einer zweiten Aussage).
3
Diese Antwort hat mich tatsächlich dazu gebracht, diese Antworten zynisch zu lesen und leicht besorgt zu sein, dass ich diesen Fehler tatsächlich gemacht habe.
Omikes
2
Wenn sich jemand gefragt hat, wie C es tatsächlich interpretiert, interpretiert ein Test, den ich mit GCC durchgeführt habe, diesen Code auf die erste Weise. tpcg.io/NIYeqx
horta
2
"Mehrdeutigkeit" ist der falsche Begriff. Es gibt keinerlei Unklarheit darüber, wie der Parser dies sehen wird: Das elsebindet gierig an das nächste, innerste if. Das Problem tritt auf, wenn C oder ähnliche Sprachen von Leuten codiert werden, die dies nicht wissen, nicht darüber nachdenken oder noch nicht genug Kaffee haben - also schreiben sie Code, von dem sie glauben, dass er eine Sache tun wird, aber die Laut Sprachspezifikation muss der Parser etwas anderes tun, was sehr unterschiedlich sein kann. Und ja, das ist ein weiteres grundsolides Argument dafür, Klammern immer einzuschließen, auch wenn die Grammatik sie als theoretisch "unnötig" kennzeichnet.
underscore_d
35

Mein allgemeines Muster lautet: Wenn es in eine Zeile passt, mache ich Folgendes:

if(true) do_something();

Wenn es eine else-Klausel gibt oder wenn der Code, für den ich ausführen möchte, eine trueerhebliche Länge hat, setzen Sie die Klammern ganz durch:

if(true) {
    do_something_and_pass_arguments_to_it(argument1, argument2, argument3);
}

if(false) {
    do_something();
} else {
    do_something_else();
}

Letztendlich kommt es auf ein subjektives Problem von Stil und Lesbarkeit an. Die allgemeine Programmierwelt teilt sich jedoch ziemlich stark in zwei Parteien (für Sprachen, die geschweifte Klammern verwenden): Verwenden Sie sie entweder ausnahmslos die ganze Zeit oder mit Ausnahmen die ganze Zeit. Ich bin Teil der letzteren Gruppe.

Matchu
quelle
4
Obwohl es so einfach wie das Schreiben ist if(true){ do_something(); }, warum sollten Sie die Chance nutzen, dass ein anderer Programmierer später einen schwerwiegenden Fehler einführt (siehe Apples "goto fail" Total SSL Code Screwup).
Craig
9
Keine Anzahl von Klammern befreit den Betreuer von der Verwendung seines Gehirns. Ich unterstütze die Idee "keine Klammern, wenn es in eine Zeile passt", weil für mich ein solches if nur eine Version des ternären if-Operators ist, bei dem man im "after:" - Teil von nichts tun muss ternär. Und warum sollte jemand ternäre Klammern einführen, wenn ?
Michal M
Ich stimme überhaupt nicht zu, dass es letztendlich subjektiv ist oder nur Stil und Lesbarkeit beeinflusst. Als jemand, der Zeit damit verschwendet hat, Probleme zu debuggen, die sich herausstellten, wurde dies durch fehlende Blocktrennzeichen verursacht (und deren Abwesenheit nicht bemerkt), weil ich einen Codierungsstil verwenden musste, der sie weglässt, wenn sie "unnötig" sind - und der über zahlreiche gelesen hat schreckliche Fehler, die sehr wohl durch solche Codierungsstile verursacht werden - ich denke, dies ist ein sehr objektives, praktisches Problem. Sicher, mit einem Stil, der Begrenzer vorschreibt, können wir sie immer noch vergessen, aber zumindest - zumindest - macht uns das Muskelgedächtnis weitaus weniger wahrscheinlich.
underscore_d
10

Ich verwende den Code-Formatierer der von mir verwendeten IDE. Das kann abweichen, kann aber in den Einstellungen / Optionen eingerichtet werden.

Ich mag dieses:

if (statement)
{
    // comment to denote in words the case
    do this;
    // keep this block simple, if more than 10-15 lines needed, I add a function for it
}
else
{
    do this;
}
Pentium10
quelle
5
Da dies ein völlig subjektives Stilproblem ist, mag ich persönlich die Redundanz der Nur-Klammer-Linien nicht. Aber hey.
Matchu
14
Ich unterstütze diesen Stil. Die meisten Leute lesen Code von links nach rechts und dadurch werden unsere Augen am linken Bildschirmrand verankert. Es hilft, Code visuell zu trennen und in logische Schrittblöcke zu extrahieren.
Mloskot
6
Ich habe diesen Stil immer bevorzugt. Viel einfacher, die entsprechende schließende Klammer zu finden. Es braucht also viel Platz? Verwenden Sie eine kleinere Schriftart.
Tag
4
Ich finde es immer einfacher, Code zu "scannen", wenn sich die geschweiften Klammern in getrennten Zeilen befinden. Das gilt für alles; Klassen, Methoden, if- und while-Anweisungen usw. Ich mochte es nie, diese erste Zahnspange in derselben Linie zu haben ...
Svish
2
Whitespace ist billig, insbesondere wenn Sie eine IDE-fähige IDE haben.
Moo
10

Die "Regel", der ich folge, lautet:

Wenn die "if" -Anweisung getestet wird, um etwas zu tun (IE-Aufruffunktionen, Konfigurieren von Variablen usw.), verwenden Sie geschweifte Klammern.

if($test)
{
    doSomething();
}

Dies liegt daran, dass Sie meiner Meinung nach klarstellen müssen, welche Funktionen aufgerufen werden und wohin der Programmfluss unter welchen Bedingungen geht. Es ist wichtig, dass der Programmierer genau versteht, welche Funktionen aufgerufen werden und welche Variablen in diesem Zustand festgelegt sind, damit er genau versteht, was Ihr Programm tut.

Wenn die "if" -Anweisung getestet wird, um etwas zu stoppen (IE-Flusssteuerung innerhalb einer Schleife oder Funktion), verwenden Sie eine einzelne Zeile.

if($test) continue;
if($test) break;
if($test) return;

In diesem Fall ist es für den Programmierer wichtig, schnell zu erkennen, in welchen Ausnahmefällen der Code nicht ausgeführt werden soll. Dies wird in $ test und nicht im Ausführungsblock behandelt.

Marcus Harrison
quelle
8

Wenn Sie die Zahnspange vom ersten Moment an haben, sollten Sie verhindern, dass Sie dies jemals debuggen müssen:

if (statement)
     do this;
else
     do this;
     do that;
Matt Bishop
quelle
1
Das scheint die akzeptierte Begründung zu sein, aber (um hier den Anwalt des Teufels zu spielen) würde eine einzige zusätzliche Syntax-Hervorhebungsregel dies nicht auch lösen, während eine Zeile gespeichert wird?
Ken
2
So wird eine IDE haben, die die Einrückung korrigiert, wenn Sie schlagen ;:)
Sam Harwell
6

Verwenden Sie geschweifte Klammern für alle if-Anweisungen, auch für einfache. Oder schreiben Sie eine einfache if-Anweisung neu, um den ternären Operator zu verwenden:

if (someFlag) {
 someVar= 'someVal1';
} else {
 someVar= 'someVal2';
}

Sieht viel schöner aus:

someVar= someFlag ? 'someVal1' : 'someVal2';

Verwenden Sie den ternären Operator jedoch nur, wenn Sie absolut sicher sind, dass in den if / else-Blöcken nichts anderes enthalten sein muss!

Leepowers
quelle
2

Nach meiner Erfahrung ist der einzige (sehr) geringfügige Vorteil des ersten Formulars die Lesbarkeit des Codes, das zweite Formular fügt "Rauschen" hinzu.

Bei modernen IDEs und Code-Autogeneration (oder Autocompletion) empfehle ich jedoch dringend, das zweite Formular zu verwenden. Sie werden keine zusätzliche Zeit damit verbringen, geschweifte Klammern einzugeben, und Sie werden einige der häufigsten Fehler vermeiden.

Es gibt genug energieaufwendige Fehler, die Leute sollten einfach keine Türen für große Zeitverschwendung öffnen.

Eine der wichtigsten Regeln beim Schreiben von Code ist die Konsistenz. Jede Codezeile sollte auf die gleiche Weise geschrieben werden, egal wer sie geschrieben hat. Strenge Verhinderung verhindert, dass Fehler "auftreten";)

Dies gilt auch für die eindeutige und explizite Benennung Ihrer Variablen, Methoden, Dateien oder für das korrekte Einrücken ...

Wenn meine Schüler diese Tatsache akzeptieren, hören sie auf, gegen ihren eigenen Quellcode zu kämpfen, und beginnen, das Codieren als eine wirklich interessante, anregende und kreative Aktivität zu betrachten. Sie fordern ihren Verstand heraus, nicht ihre Nerven!

thomas.g
quelle
2

Es ist eine Frage der Präferenz. Ich persönlich verwende beide Stile. Wenn ich mir ziemlich sicher bin, dass ich keine weiteren Anweisungen hinzufügen muss, verwende ich den ersten Stil, aber wenn dies möglich ist, verwende ich den zweiten. Da Sie dem ersten Stil keine weiteren Aussagen hinzufügen können, habe ich gehört, dass einige Leute davon abraten, ihn zu verwenden. Bei der zweiten Methode ist jedoch eine zusätzliche Codezeile erforderlich. Wenn Sie (oder Ihr Projekt) diese Art von Codierungsstil verwenden, wird die erste Methode für einfache if-Anweisungen sehr bevorzugt:

if(statement)
{
    do this;
}
else
{
    do this;
}

Ich denke jedoch, dass die beste Lösung für dieses Problem in Python ist. Mit der Whitespace-basierten Blockstruktur haben Sie nicht zwei verschiedene Methoden zum Erstellen einer if-Anweisung: Sie haben nur eine:

if statement:
    do this
else:
    do this

Während dies das "Problem" hat, dass Sie die geschweiften Klammern überhaupt nicht verwenden können, erhalten Sie den Vorteil, dass der erste Stil keine Zeilen mehr enthält und die Möglichkeit besteht, weitere Anweisungen hinzuzufügen.

Grant Paul
quelle
Ich selbst halte die Art und Weise, wie Python mit if-else-Anweisungen
umgeht, für
1

Ich habe immer versucht, meinen Code zum Standard zu machen und ihm so nahe wie möglich zu kommen. Dies erleichtert anderen das Lesen, wenn sie für die Aktualisierung verantwortlich sind. Wenn Sie Ihr erstes Beispiel machen und in der Mitte eine Zeile hinzufügen, schlägt dies fehl.

Funktioniert nicht:

if (Anweisung) dies tun; und das; sonst mach das;

Joe
quelle
1

Persönlich verwende ich den ersten Stil nur, um eine Ausnahme auszulösen oder vorzeitig von einer Methode zurückzukehren. Wie Argument Prüfen am Anfang einer Funktion, weil ich in diesen Fällen selten mehr als eine Sache zu tun habe und es nie eine andere gibt.

Beispiel:

if (argument == null)
    throw new ArgumentNullException("argument");

if (argument < 0)
    return false;

Ansonsten benutze ich den zweiten Stil.

Nate Heinrich
quelle
1

Meine persönliche Präferenz ist die Verwendung einer Mischung aus Leerzeichen und Klammern wie folgt:

if( statement ) {

    // let's do this

} else {

    // well that sucks

}

Ich denke, das sieht sauber aus und macht meinen Code sehr einfach zu lesen und vor allem - Debuggen.

Simon
quelle
0

Ich stimme den meisten Antworten darin zu, dass es besser ist, in Ihrem Code explizit zu sein und geschweifte Klammern zu verwenden. Persönlich würde ich eine Reihe von Codierungsstandards übernehmen und sicherstellen, dass jeder im Team sie kennt und sich anpasst. Wo ich arbeite, verwenden wir von IDesign.net veröffentlichte Codierungsstandards für .NET-Projekte.

Kane
quelle
0

Ich ziehe es vor, eine geschweifte Klammer zu setzen. Aber manchmal hilft der ternäre Operator.

Anstatt :

int x = 0;
if (condition) {
    x = 30;
} else {
    x = 10;
}

Man sollte einfach tun: int x = condition ? 30 : 20;

Stellen Sie sich auch einen Fall vor:

if (condition)
    x = 30;
else if (condition1)
    x = 10;
else if (condition2)
    x = 20;

Es wäre viel besser, wenn Sie die geschweifte Klammer einsetzen.

fastcodejava
quelle