Soll ich frühzeitig von einer Funktion zurückkehren oder eine if-Anweisung verwenden? [geschlossen]

304

Ich habe diese Art von Funktion oft in beiden Formaten geschrieben und mich gefragt, ob ein Format einem anderen vorgezogen wird und warum.

public void SomeFunction(bool someCondition)
{
    if (someCondition)
    {
        // Do Something
    }
}

oder

public void SomeFunction(bool someCondition)
{
    if (!someCondition)
        return;

    // Do Something
}

Normalerweise codiere ich mit dem ersten, da mein Gehirn beim Codieren so arbeitet, obwohl ich den zweiten vorzuziehen denke, da er sich sofort um die Fehlerbehandlung kümmert und das Lesen erleichtert

Rachel
quelle
9
Ich bin ein bisschen spät dran für diese Diskussion, also werde ich das nicht in eine Antwort stecken. Vor zwei Jahren habe ich auch darüber nachgedacht: lecterror.com/articles/view/code-formatting-and-readability Ich finde, dass der zweite einfacher zu lesen, zu ändern, zu warten und zu debuggen ist. Aber vielleicht bin das nur ich :)
Dr. Hannibal Lecter
4
jetzt ist diese frage ein gutes beispiel für eine meinungsbasierte frage
Rudolf Olah
2
Was ist, wenn es keinen absoluten Beweis in die eine oder andere Richtung gibt? Wenn genügend Argumente in die eine oder andere Richtung geliefert werden und eine Abstimmung stattfindet, wenn die Antwort richtig ist, ist dies sehr nützlich. Ich halte solche abschließenden Fragen für schädlich für den Wert dieser Website.
gsf
9
Und ich mag meinungsbasierte Fragen und Antworten. Sie sagen mir, was die Mehrheit bevorzugt, und so kann ich den Code schreiben, damit andere ihn lesen können.
Zygimantas

Antworten:

402

Ich bevorzuge den zweiten Stil. Schieben Sie ungültige Fälle zuerst aus dem Weg, indem Sie sie entweder beenden oder gegebenenfalls Ausnahmen auslösen, setzen Sie eine Leerzeile ein und fügen Sie dann den "echten" Hauptteil der Methode hinzu. Ich finde es leichter zu lesen.

Mason Wheeler
quelle
7
Smalltalk nennt diese "Schutzklauseln". Zumindest nennt Kent Beck sie in Smalltalk Best Practice Patterns so. Ich weiß nicht, ob es üblich ist.
Frank Shearar
154
Wenn Sie vorzeitig beenden, können Sie Dinge von Ihrem begrenzten mentalen Stapel entfernen. :)
Joren
50
Ich habe zuvor gehört, dass dies als "das Türsteher-Muster" bezeichnet wird - Beseitigen Sie schlimme Fälle, bevor sie in die Tür gelangen.
RevBingo
14
Ich würde sogar so weit gehen und sagen, dass dies definitiv das EINZIGE Richtige ist.
Oliver Weiler
38
Außerdem fügen Sie nicht ständig Einzüge hinzu, wenn Sie die Grenzfälle am Anfang loswerden.
Doppelgreener
170

Auf jeden Fall das letztere. Ersteres sieht im Moment nicht schlecht aus, aber wenn Sie komplexeren Code erhalten, kann ich mir nicht vorstellen, dass irgendjemand dies denken würde:

public int SomeFunction(bool cond1, string name, int value, AuthInfo perms)
{
    int retval = SUCCESS;
    if (someCondition)
    {
        if (name != null && name != "")
        {
            if (value != 0)
            {
                if (perms.allow(name)
                {
                    // Do Something
                }
                else
                {
                    reval = PERM_DENY;
                }
            }
            else
            {
                retval = BAD_VALUE;
            }
        }
        else
        {
            retval = BAD_NAME;
        }
    }
    else
    {
        retval = BAD_COND;
    }
    return retval;
}

ist besser lesbar als

public int SomeFunction(bool cond1, string name, int value, AuthInfo perms)
{
    if (!someCondition)
        return BAD_COND;

    if (name == null || name == "")
        return BAD_NAME;

    if (value == 0)
        return BAD_VALUE;

    if (!perms.allow(name))
        return PERM_DENY;

    // Do something
    return SUCCESS;
}

Ich gebe zu, ich habe den Vorteil einzelner Ausstiegspunkte nie verstanden.

Jason Viers
quelle
20
Der Vorteil eines einzelnen Ausstiegspunkts ist, dass ... es einen einzelnen Ausstiegspunkt gibt! Mit Ihrem Beispiel gibt es mehrere Punkte, die zurückkehren könnten. Bei einer komplexeren Funktion kann dies zu einem Sammelpunkt werden, wenn sich das Format des Rückgabewerts ändert. Es gibt natürlich Zeiten, in denen das Erzwingen eines einzelnen Ausstiegspunkts keinen Sinn ergibt.
JohnL
71
@JohnL große Funktionen sind das Problem, nicht mehrere Austrittspunkte. Es sei denn, Sie arbeiten in einem Kontext, in dem ein zusätzlicher Funktionsaufruf Ihren Code ungemein verlangsamt ...
Dan Rosenstark
4
@Yar: Stimmt, aber der Punkt steht. Ich werde nicht versuchen, jemanden zu konvertieren, und ich habe nur auf den Vorteil hingewiesen, möglichst wenige Ausstiegspunkte anzustreben (und Jasons Beispiel war sowieso eine Art Strohmann). Wenn Sie sich das nächste Mal die Haare aus dem Kopf ziehen, um herauszufinden, warum SomeFunction manchmal ungerade Werte zurückgibt, möchten Sie vielleicht, dass Sie kurz vor der Rückkehr einen Protokollierungsaufruf hinzufügen . Viel einfacher zu debuggen, wenn es nur einen der Fehler gibt! :)
JohnL
76
@Jason Viers Als ob eine einzige return value;hilft!?! Dann muss man ein halbes Dutzend jagen value = ..., mit dem Nachteil, dass man nie sicher ist, dass sich der Wert zwischen dieser Aufgabe und der endgültigen Rückgabe nicht ändert. Zumindest eine sofortige Rückkehr ist klar, dass nichts mehr das Ergebnis verändern wird.
Sjoerd
5
@ Sjoed: Ich habe Sjoerd hier als Zweites. Wenn Sie das Ergebnis protokollieren möchten, können Sie sich am Anruferstandort anmelden. Wenn Sie den Grund wissen möchten, müssen Sie sich an jedem Ausgangspunkt / jeder Zuordnung anmelden, damit beide in dieser Hinsicht identisch sind.
Matthieu M.
32

Es kommt darauf an - Im Allgemeinen werde ich nicht allzu sehr versuchen, eine Reihe von Code zu verschieben, um die Funktion frühzeitig zu beenden - der Compiler kümmert sich im Allgemeinen darum. Das heißt aber, wenn es oben einige grundlegende Parameter gibt, die ich brauche und ansonsten nicht weitermachen kann, werde ich früh ausbrechen. Ebenso, wenn eine Bedingung einen Riesenblock ifin der Funktion erzeugt, werde ich es als Ergebnis auch früh ausbrechen lassen.

Das heißt, wenn eine Funktion beim Aufrufen einige Daten benötigt, werde ich normalerweise eine Ausnahme auslösen (siehe Beispiel), anstatt nur zurückzukehren.

public int myFunction(string parameterOne, string parameterTwo) {
  // Can't work without a value
  if (string.IsNullOrEmpty(parameterOne)) {
    throw new ArgumentNullException("parameterOne");
  } 
  if (string.IsNullOrEmpty(parameterTwo)) {
    throw new ArgumentNullException("parameterTwo");
  }

  // ...      
  // Do some work
  // ...

  return value;
}
rjzii
quelle
9
Und wenn das Endergebnis wartbar ist, wen interessiert es, welcher Stil ausgewählt wurde?
Jeff Siver
3
@ Jeff Siver - Also, warum dies tendenziell eine Frage im Stil des "Heiligen Krieges" ist, hängt letztendlich von den persönlichen Vorlieben und den Aussagen eines internen Styleguides ab.
rjzii
1
Der entscheidende Vorteil ist, dass er eine Ausnahme auslöst, anstatt früh zurückzukehren. Der Rückgabewert sollte nicht für Gültigkeitsprüfungen verwendet werden. Was wäre, wenn Sie unter verschiedenen Bedingungen den Code mithilfe der Methode wissen lassen wollten, warum er fehlgeschlagen ist? Plötzlich können Sie tatsächliche Geschäftsdaten, nichts (leeres Ergebnis) oder viele verschiedene Zeichenfolgen, Codes, Zahlen usw. von einer einzigen Methode zurückgeben. Nur um zu beschreiben, warum es fehlgeschlagen ist. Nein Danke.
DanMan
Was ist mit der zyklomatischen Komplexität, die mein Compiler vorschlägt? Ist es nicht besser, Code nicht zu verschachteln, wenn man ihm helfen kann?
l - '' '' ''---------' '' '' '' '' ''
24

Ich bevorzuge die vorzeitige Rückkehr.

Wenn Sie einen Einstiegs- und einen Ausstiegspunkt haben, müssen Sie immer den gesamten Code in Ihrem Kopf bis zum Ausstiegspunkt verfolgen (Sie wissen nie, ob ein anderes Stück Code unter dem Ergebnis noch etwas anderes bewirkt, also Sie müssen es aufspüren, bis das existiert). Sie tun das, egal welcher Zweig das Endergebnis bestimmt. Dies ist schwer zu folgen.

Wenn ein Eintrag und mehrere vorhanden sind, kehren Sie zurück, wenn Sie Ihr Ergebnis haben, und verfolgen es nicht bis zum Ende, um festzustellen, dass niemand etwas anderes daran tut (da es seit Ihrer Rückkehr nichts anderes mehr gibt). Es ist, als würde man den Methodenkörper in mehrere Schritte aufteilen, wobei jeder Schritt die Möglichkeit bietet, das Ergebnis zurückzugeben oder den nächsten Schritt sein Glück versuchen zu lassen.

user7197
quelle
13

Bei der C-Programmierung, bei der Sie manuell bereinigen müssen, gibt es eine Menge zu sagen für die Ein-Punkt-Rückgabe. Auch wenn es derzeit nicht erforderlich ist, etwas zu bereinigen, kann jemand Ihre Funktion bearbeiten, etwas zuweisen und es vor der Rückgabe bereinigen. In diesem Fall wird es ein Albtraum sein, alle Rückgabeanweisungen durchzusehen.

In der C ++ - Programmierung gibt es Destruktoren und sogar jetzt Scope-Exit-Guards. All dies muss vorhanden sein, um sicherzustellen, dass der Code in erster Linie ausnahmesicher ist. Code ist also gut gegen vorzeitiges Beenden geschützt und hat daher keinen logischen Nachteil und ist lediglich ein Stilproblem.

Ich weiß nicht genug über Java, ob "finally" -Blockcode aufgerufen wird und ob Finalizer die Situation bewältigen können, die erforderlich ist, um sicherzustellen, dass etwas passiert.

C # Ich kann auf keinen Fall antworten.

D-language bietet Ihnen die richtigen eingebauten Scope-Exit-Guards und ist daher gut auf ein frühzeitiges Verlassen vorbereitet und sollte daher kein anderes Problem als den Stil darstellen.

Funktionen sollten natürlich nicht so lang sein, und wenn Sie eine große switch-Anweisung haben, wird Ihr Code wahrscheinlich auch schlecht berücksichtigt.

Goldesel
quelle
1
C ++ ermöglicht eine sogenannte Rückgabewertoptimierung, die es dem Compiler ermöglicht, den Kopiervorgang, der normalerweise bei der Rückgabe eines Werts auftreten würde, im Wesentlichen wegzulassen. Unter verschiedenen Bedingungen ist dies jedoch schwierig und mehrere Rückgabewerte sind einer dieser Fälle. Mit anderen Worten, die Verwendung mehrerer Rückgabewerte in C ++ kann Ihren Code tatsächlich verlangsamen. Dies gilt mit Sicherheit für MSC, und da die Implementierung von RVO mit mehreren möglichen Rückgabewerten sehr schwierig (wenn nicht unmöglich) ist, ist dies wahrscheinlich ein Problem bei allen Compilern.
Eamon Nerbonne
1
Verwenden Sie in C einfach gotound möglicherweise eine Zweipunktrückgabe. Beispiel (Code-Formatierung in Kommentaren nicht möglich):foo() { init(); if (bad) goto err; bar(); if (bad) goto err; baz(); return 0; err: cleanup(); return 1; }
mirabilos
1
Anstelle eines goto bevorzuge ich "Extract Method". Wenn Sie glauben, eine Rückgabewertvariable oder ein goto implementieren zu müssen, um sicherzustellen, dass Ihr Bereinigungscode immer aufgerufen wird, müssen Sie ihn in mehrere Funktionen aufteilen. Auf diese Weise können Sie Ihren komplexen bedingten Code mithilfe von Schutzklauseln und anderen Techniken zur vorzeitigen Rückgabe vereinfachen und gleichzeitig sicherstellen, dass der Bereinigungscode immer ausgeführt wird.
BrandonLWhite
"jemand könnte Ihre Funktion bearbeiten" - das ist eine so lächerliche Erklärung für die Entscheidungsfindung. Jeder kann in Zukunft alles machen. Es bedeutet nicht, dass Sie heute etwas Bestimmtes tun sollten, um zu verhindern, dass in Zukunft jemand etwas kaputt macht.
Victor Yarema
Wird aufgerufen, um Ihren Code wartbar zu machen. In der realen Welt wird Code für geschäftliche Zwecke geschrieben und manchmal muss er später von einem Entwickler geändert werden. Zu der Zeit, als ich diese Antwort schrieb, hatte ich CURL gepatcht, um das Caching einzuführen und mich an das Spaghetti-Durcheinander zu erinnern, dass es wirklich eines richtigen Umschreibens in modernem C ++
bedurfte
9

Frühe Rückkehr zum Sieg. Sie können hässlich wirken, aber viel weniger hässlich als große ifVerpackungen, insbesondere wenn mehrere Bedingungen zu prüfen sind.

STW
quelle
9

Ich benutze beides.

Wenn DoSomethinges sich um 3-5 Codezeilen handelt, sieht der Code mit der ersten Formatierungsmethode einfach nur gut aus.

Aber wenn es viel mehr Zeilen als das hat, dann bevorzuge ich das zweite Format. Ich mag es nicht, wenn sich die öffnende und schließende Klammer nicht auf demselben Bildschirm befinden.

Azheglov
quelle
2
Schön auf keinen Fall! Zu viel Einrückung!
JimmyKane
@JimmyKane Es gibt nur so viele Einrückungen, die in 3-5 Zeilen auftreten können, besonders wenn Sie 2 (?) Zeilen pro Ebene benötigen, wird der Rest eingerückt: Eine für die Kontrollstruktur und den Beginn des Blocks, eine für das Ende des Blocks.
Deduplizierer
8

Ein klassischer Grund für Single-Entry-Single-Exit ist, dass ansonsten die formale Semantik unaussprechlich hässlich wird (der gleiche Grund, warum GOTO als schädlich eingestuft wurde).

Anders ausgedrückt, es ist einfacher zu überlegen, wann Ihre Software die Routine beendet, wenn Sie nur 1 Rückkehr haben. Das ist auch ein Argument gegen Ausnahmen.

Normalerweise minimiere ich den Early-Return-Ansatz.

Paul Nathan
quelle
Für ein formales Analysewerkzeug können Sie jedoch eine äußere Funktion mit der Semantik synthetisieren, die das Werkzeug benötigt, und den Code für den Menschen lesbar halten.
Tim Williscroft
@Tim. Das hängt davon ab, wie viel Dinking Sie machen möchten und was Sie analysieren. Ich finde SESE ziemlich lesbar, wenn der Programmierer bei den Dingen vernünftig war.
Paul Nathan
Meine Einstellung zur Analyse ist geprägt von Optimierungen aus dem Self-Projekt. 99% der dynamischen Methodenaufrufe können statisch aufgelöst und beseitigt werden. Dann können Sie einen ziemlich geraden Code analysieren. Als funktionierender Programmierer kann ich davon ausgehen, dass der größte Teil des Codes, an dem ich arbeite, von durchschnittlichen Programmierern geschrieben wurde. Sie werden also keinen sehr netten Code schreiben.
Tim Williscroft
@ Tim: Fair genug. Obwohl ich mich gezwungen fühle darauf hinzuweisen, dass statische Sprachen immer noch viel zu tun haben.
Paul Nathan
Ein Grund, der Ausnahmen nicht standhält. Das ist der Grund, warum Single-Exit in C großartig ist, Sie aber in C ++ nichts kaufen.
Peterchen
7

Persönlich bevorzuge ich zu Beginn die Prüfung auf Bestehen / Nichtbestehen. Dadurch kann ich die meisten der häufigsten Fehler ganz oben in der Funktion mit dem Rest der folgenden Logik zusammenfassen.

Nathan
quelle
6

Es hängt davon ab, ob.

Vorzeitige Rückkehr, wenn eine offensichtliche Sackgasse vorliegt, auf die sofort geprüft werden muss, und die Ausführung des Restes der Funktion sinnlos machen würde. *

Stellen Sie Retval + Single Return ein, wenn die Funktion komplexer ist und andernfalls mehrere Exit Points haben könnte (Lesbarkeitsproblem).

* Dies kann häufig auf ein Designproblem hinweisen. Wenn Sie feststellen, dass viele Ihrer Methoden einen externen / paramater-Status oder dergleichen überprüfen müssen, bevor Sie den Rest des Codes ausführen, sollte dies wahrscheinlich vom Aufrufer behandelt werden.

Bobby Tische
quelle
6
Wenn ich Code schreibe, der geteilt werden kann, lautet mein Mantra "Angenommen, nichts. Vertraue niemandem." Sie sollten Ihre Eingaben und jeden externen Zustand, von dem Sie abhängig sind, immer validieren. Es ist besser, eine Ausnahme auszulösen, als möglicherweise etwas zu beschädigen, weil Ihnen jemand schlechte Daten gegeben hat.
TMN
@TMN: Guter Punkt.
Bobby Tables
2
Entscheidend dabei ist, dass Sie in OO eine Ausnahme auslösen und nicht zurückgeben . Mehrfache Rückgaben können schlecht sein, mehrfache Ausnahmewürfe sind nicht unbedingt ein Codegeruch.
Michael K
2
@MichaelK: Eine Methode sollte eine Ausnahme bilden, wenn die Nachbedingung nicht erfüllt werden kann. In einigen Fällen sollte eine Methode vorzeitig beendet werden, da die Nachbedingung bereits vor dem Start der Funktion erreicht wurde. Wenn Sie beispielsweise die Methode "Steuerelementbeschriftung festlegen" aufrufen, um die Beschriftung eines Steuerelements zu ändern, ist die Beschriftung Freddes Fensters bereits vorhanden. Wenn Sie Fredden Namen des Steuerelements auf den aktuellen Status setzen, wird ein Neuzeichnen erzwungen (was in einigen Fällen möglicherweise hilfreich ist) ärgerlich in der einen Hand), wäre es völlig vernünftig, die Set-Name-Methode vorzeitig zu beenden, wenn der alte und der neue Name übereinstimmen.
Superkatze
3

Verwenden Sie ein If

In Don Knuths Buch über GOTOs habe ich gelesen, dass er in einer if-Anweisung immer den wahrscheinlichsten Zustand an erster Stelle hat. Unter der Annahme, dass dies immer noch eine vernünftige Idee ist (und nicht aus reiner Rücksicht auf die Geschwindigkeit der Ära). Ich würde sagen, frühe Rückgaben sind keine gute Programmierpraxis, insbesondere angesichts der Tatsache, dass sie häufig zur Fehlerbehandlung verwendet werden, es sei denn, Ihr Code scheitert eher als nicht :-)

Wenn Sie den obigen Hinweisen folgen, müssen Sie diese Rückgabe am Ende der Funktion einfügen, und dann können Sie sie dort auch gar nicht als Rückgabe bezeichnen. Setzen Sie einfach den Fehlercode und geben Sie sie in zwei Zeilen zurück. Dadurch wird das Ideal 1 Einfahrt 1 Ausfahrt erreicht.

Delphi-spezifisch ...

Ich bin der Meinung, dass dies eine gute Programmierpraxis für Delphi-Programmierer ist, obwohl ich keinen Beweis habe. Vor D2009 haben wir keinen atomaren Weg, um einen Wert zurückzugeben, wir haben exit;und result := foo;oder wir könnten einfach Ausnahmen auslösen.

Wenn du ersetzen müsstest

if (true) {
 return foo;
} 

zum

if true then 
begin
  result := foo; 
  exit; 
end;

Sie könnten es einfach satt haben, das an der Spitze jeder Ihrer Funktionen zu sehen und es vorzuziehen

if false then 
begin
  result := bar;

   ... 
end
else
   result := foo;

und nur exitganz vermeiden .

Peter Turner
quelle
2
Mit neuerem Delphis könnte es abgekürzt werden, dass if true then Exit(foo);ich oft die Technik verwende, um zuerst resultauf nilbzw. zu initialisieren FALSE, dann alle Fehlerbedingungen zu überprüfen und nur, Exit;ob eine erfüllt ist. Der Erfolgsfall resultwird dann (typischerweise) irgendwo am Ende der Methode festgelegt.
JensG
Ja, ich mag diese neue Funktion, auch wenn es so aussieht, als wäre es nur eine Süßigkeit, Java-Programmierer zu befriedigen. Als nächstes können wir unsere Variablen in den Prozeduren definieren.
Peter Turner
Und C # -Programmierer. Ja, um ehrlich zu sein, ich würde das in der Tat nützlich finden, da es die Anzahl der Zeilen zwischen Deklaration und Verwendung verringert (IIRC gibt es sogar eine Metrik dafür, vergessen Sie den Namen).
JensG
2

Ich stimme der folgenden Aussage zu:

Ich persönlich bin ein Fan von Schutzklauseln (das zweite Beispiel), da dies das Einrücken der Funktion verringert. Einige Leute mögen sie nicht, weil es zu mehreren Rückgabepunkten der Funktion führt, aber ich denke, dass es bei ihnen klarer ist.

Entnommen aus dieser Frage im Stackoverflow .

Toto
quelle
+1 Für Schutzklauseln. Ich bevorzuge auch eine positiv ausgerichtete Wache, zB: if (condition = false) return im Gegensatz zu if (! Condition) return
JustinC
1

Ich verwende heutzutage fast ausschließlich frühe Renditen, und zwar im Extremfall. Ich schreibe das

self = [super init];

if (self != nil)
{
    // your code here
}

return self;

wie

self = [super init];
if (!self)
    return;

// your code here

return self;

aber es ist wirklich egal. Wenn Ihre Funktionen mehr als eine oder zwei Verschachtelungsebenen enthalten, müssen diese aufgelöst werden.

Dan Rosenstark
quelle
Genau. Einrückungen verursachen Probleme beim Lesen. Je weniger Einrückung desto besser. Ihr einfaches Beispiel hat den gleichen Grad an Einrückung, aber dieses erste Beispiel wird mit Sicherheit zu mehr Einrückungen führen, die mehr Gehirnleistung erfordern.
user441521
1

Ich würde lieber schreiben:

if(someCondition)
{
    SomeFunction();
}
Josh K
quelle
2
eww. Ist das eine Vorvalidierung? Oder handelt es sich um ein Validierungsverfahren DoSomeFunctionIfSomeCondition?
STW
Wie werden Ihre Bedenken dadurch getrennt?
11.
2
Sie verletzen die Kapselung, indem Sie die Implementierung der Funktion (ihre Abhängigkeitslogik) extern machen.
TMN
1
Wenn dies in einer öffentlichen Methode ausgeführt wird und SomeFunction () eine private Methode in derselben Klasse ist, ist dies möglicherweise in Ordnung. Aber wenn jemand anderes SomeFunction () aufruft, müssten Sie die Prüfungen dort duplizieren. Ich finde es besser, jede Methode dazu zu bringen, sich um das zu kümmern, was sie für ihre Arbeit benötigt. Niemand sonst sollte das wissen müssen.
Per Wiklander
2
Dies ist definitiv der Stil, den Robert C. Martin in "Clean Code" vorschlägt. Eine Funktion sollte nur eines tun. In "Implementation Patterns" schlägt Kent Beck jedoch vor, dass die zweite der beiden im OP vorgeschlagenen Optionen besser ist.
Scott Whitlock
1

Wie du schreibe ich normalerweise die erste, bevorzuge aber die letzte. Wenn ich viele verschachtelte Überprüfungen habe, refactor ich normalerweise zur zweiten Methode.

Mir gefällt nicht, wie die Fehlerbehandlung von der Prüfung wegbewegt wird.

if not error A
  if not error B
    if not error C
      // do something
    else handle error C
  else handle error B
else handle error A

Ich bevorzuge das:

if error A
  handle error A; return
if error B
  handle error B; return
if error C
  handle error C; return

// do something
Ruck
quelle
0

Die Bedingungen oben werden "Vorbedingungen" genannt. Indem Sie setzen if(!precond) return;, listen Sie visuell alle Voraussetzungen auf.

Die Verwendung des großen "if-else" -Blocks kann den Einrückungsaufwand erhöhen (ich habe das Zitat über dreistufige Einrückungen vergessen).

Ming-Tang
quelle
2
Was? Sie können in Java nicht frühzeitig zurückkehren? C #, VB (.NET und 6) und anscheinend Java (was ich angenommen hatte, aber nachschlagen musste, da ich die Sprache seit 15 Jahren nicht mehr verwendet habe) ermöglichen alle eine vorzeitige Rückkehr. Beschuldigen Sie also nicht, dass "stark typisierte Sprachen" nicht über diese Funktion verfügen. stackoverflow.com/questions/884429/…
ps2goat
-1

Ich ziehe es vor, wenn Aussagen klein sind.

Wählen Sie also zwischen:

if condition:
   line1
   line2
    ...
   line-n

und

if not condition: return

line1
line2
 ...
line-n

Ich würde wählen, was Sie als "frühe Rückkehr" beschrieben haben.

Wohlgemerkt, ich kümmere mich nicht um frühe Rückgaben oder was auch immer, ich mag es einfach, den Code zu vereinfachen, die Textkörper von if-Anweisungen zu verkürzen usw.

Verschachtelt, wenn's und für's und für's schrecklich sind , meide sie um jeden Preis.

hasen
quelle
-2

Wie andere sagen, kommt es darauf an. Für kleine Funktionen, die Werte zurückgeben, kann ich frühe Rückgaben codieren. Bei umfangreichen Funktionen möchte ich jedoch immer einen Platz im Code haben, an dem ich weiß, dass ich etwas einfügen kann, das ausgeführt wird, bevor es zurückkehrt.

Mike Dunlavey
quelle
-2

Ich übe auf Funktionsebene ausfallsicher. Es hält den Code konsistent und sauber (für mich und die, mit denen ich gearbeitet habe). Aus diesem Grund komme ich immer früh zurück.

Für einige häufig geprüfte Bedingungen können Sie Aspekte für diese Prüfungen implementieren, wenn Sie AOP verwenden.

Steven Evers
quelle