Manchmal stoße ich auf Code, der dem folgenden Beispiel ähnelt (was diese Funktion genau tut, ist nicht Gegenstand dieser Frage):
function doSomething(value) {
if (check1(value)) {
return -1;
}
else if (check2(value)) {
return value;
}
else {
return false;
}
}
Wie Sie sehen, if
werden else if
und else
-Anweisungen in Verbindung mit der return
Anweisung verwendet. Für einen zufälligen Betrachter scheint dies ziemlich intuitiv zu sein, aber ich denke, es wäre eleganter (aus der Sicht eines Softwareentwicklers), das else
-s wegzulassen und den Code wie folgt zu vereinfachen:
function doSomething(value) {
if (check1(value)) {
return -1;
}
if (check2(value)) {
return value;
}
return false;
}
Dies ist sinnvoll, da alles, was auf eine return
Anweisung folgt (im selben Bereich), niemals ausgeführt wird, sodass der obige Code semantisch dem ersten Beispiel entspricht.
Welche der oben genannten Optionen passt besser zu den bewährten Codierungsmethoden? Gibt es bei beiden Methoden Nachteile hinsichtlich der Lesbarkeit des Codes?
Bearbeiten: Es wurde ein doppelter Vorschlag mit dieser Frage als Referenz gemacht. Ich glaube, meine Frage berührt ein anderes Thema, da ich nicht nach doppelten Aussagen frage, wie sie in der anderen Frage dargestellt sind. Beide Fragen zielen darauf ab, Wiederholungen zu reduzieren, wenn auch auf leicht unterschiedliche Weise.
else
ist ein geringeres Problem, das größere Problem ist, dass Sie offensichtlich zwei Datentypen aus einer einzelnen Funktion zurückgeben, was die API der Funktion unvorhersehbar macht.-1
ist eine Zahl,false
ist ein Boolescher Wert undvalue
wird hier nicht angegeben, sodass es sich um einen beliebigen Objekttyp handeln kann.value
ist eigentlich eine ganze Zahl. Wenn es irgendetwas sein kann, ist das noch schlimmer.Antworten:
Ich mag das ohne
else
und hier ist warum:Weil das nichts kaputt machte, was es nicht sollte.
Hassen Sie die gegenseitige Abhängigkeit in all ihren Formen (einschließlich der Benennung einer Funktion
check2()
). Isolieren Sie alles, was isoliert werden kann. Manchmal braucht man das,else
aber das sehe ich hier nicht.quelle
if
Blocks von} //else
, um beim Lesen des Codes zu verdeutlichen, dass die einzige beabsichtigte Ausführung nach demif
Codeblock darin besteht, dass die Bedingung in derif
Anweisung falsch war. Ohne etwas wie dieses, insbesondere wenn der Code innerhalb desif
Blocks komplexer wird, kann es sein, dass nicht klar ist, wer den Code verwaltet, dass die Absicht bestand, niemals nach demif
Block auszuführen , wenn dieif
Bedingung wahr ist.if
, um zu verdeutlichen, dass dieser Codeabschnitt fertig ist und die Struktur fertig ist. Dazu tue ich, was ich hier nicht getan habe (weil ich nicht durch andere Änderungen vom Hauptpunkt des OP ablenken wollte). Ich tue das Einfachste, was ich kann, um all das zu erreichen, ohne abzulenken. Ich füge eine Leerzeile hinzu.Ich denke, es hängt von der Semantik des Codes ab. Wenn Ihre drei Fälle voneinander abhängig sind, geben Sie dies explizit an. Dies erhöht die Lesbarkeit des Codes und erleichtert das Verständnis für andere. Beispiel:
Hier sind Sie eindeutig auf den Wert von
x
in allen drei Fällen angewiesen. Wenn Sie den letzten weglassenelse
würden, wäre dies weniger klar.Wenn Ihre Fälle nicht direkt voneinander abhängen, lassen Sie es weg:
Es ist schwer, dies in einem einfachen Beispiel ohne Kontext zu zeigen, aber ich hoffe, Sie verstehen meinen Standpunkt.
quelle
Ich ziehe die zweite Option (trennen
ifs
ohneelse if
und frühreturn
) ABER das ist , solange die Codeblöcke kurz sind .Wenn Codeblöcke lang sind, ist es besser
else if
, sie zu verwenden , da Sie ansonsten nicht genau wissen, über welche Ausstiegspunkte der Code verfügt.Beispielsweise:
In diesem Fall ist es besser
else if
, den Rückgabewert in einer Variablen zu speichern und am Ende nur einen Rückgabesatz zu haben.Da man sich jedoch darum bemühen sollte, dass Funktionen kurz sind, würde ich sagen, halten Sie sie kurz und beenden Sie sie früh wie in Ihrem ersten Code-Snippet.
quelle
return
liegt innerhalb von 3 Zeilen, istif
also nicht anders alselse if
nach 200 Codezeilen. Der hier vorgestellte Single Return-Stil ist eine Tradition von c und anderen Sprachen, die keine Fehler mit Ausnahmen melden. Es ging darum, einen einzigen Ort zum Bereinigen von Ressourcen zu schaffen. Ausnahmesprachen verwenden dafür einenfinally
Block. Ich nehme an, dass dies auch einen Platz schafft, an dem ein Haltepunkt gesetzt werden kann, wenn Ihr Debugger nicht zulässt, dass Sie einen Haltepunkt auf die Funktionen setzen, die die geschweifte Klammer schließen.retVal
überhaupt nicht. Wenn Sie eine Funktion sicher verlassen können, tun Sie dies sofort, ohne den sicheren Wert zuzuweisen, der an eine Variable eines einzelnen Exits der Funktion zurückgegeben werden soll. Wenn Sie den einzelnen Rückgabewert in einer sehr langen Funktion verwenden, vertraue ich im Allgemeinen anderen Programmierern nicht und suche im Rest der Funktion auch nach anderen Änderungen des Rückgabewerts. Schnell scheitern und früh zurückkehren sind unter anderem zwei Regeln, nach denen ich lebe.Ich benutze beides unter verschiedenen Umständen. Bei einer Validierungsprüfung lasse ich das übrige weg. In einem Kontrollfluss verwende ich das else.
vs
Der erste Fall sieht eher so aus, als würden Sie zuerst alle Voraussetzungen prüfen, diese aus dem Weg räumen und dann zum eigentlichen Code übergehen, den Sie ausführen möchten. Daher gehört der Code, den Sie unbedingt ausführen möchten, direkt zum Funktionsumfang. darum geht es in der Funktion wirklich.
Der zweite Fall sieht eher so aus, als ob beide Pfade gültiger auszuführender Code sind, der für die Funktion genauso relevant ist wie der andere, basierend auf einer bestimmten Bedingung. Als solche gehören sie in ähnlichen Umfangsebenen zueinander.
quelle
Die einzige Situation, in der ich jemals gesehen habe, dass es wirklich darauf ankommt, ist folgender Code:
Hier stimmt eindeutig etwas nicht. Das Problem ist, es ist nicht klar, ob
return
es hinzugefügt oderArrays.asList
entfernt werden sollte. Sie können dies nicht beheben, ohne die zugehörigen Methoden eingehender zu untersuchen. Sie können diese Mehrdeutigkeit vermeiden, indem Sie immer vollständige if-else-Blöcke verwenden. Dies:Kompiliert nicht (in statisch überprüften Sprachen), es sei denn, Sie fügen explizite Rückgabe zuerst hinzu
if
.Einige Sprachen erlauben nicht einmal den ersten Stil. Ich versuche es nur im zwingenden Kontext oder als Voraussetzung für lange Methoden zu verwenden:
quelle
Es ist wirklich verwirrend, drei Abbrüche von dieser Funktion zu haben, wenn Sie versuchen, dem Code zu folgen und schlechte Praktiken anzuwenden.
Wenn Sie einen einzelnen Austrittspunkt für die Funktion haben, sind die anderen erforderlich.
Lassen Sie uns sogar noch weiter gehen.
Fairerweise könnte man für eine einzelne vorzeitige Rückkehr bei der Eingabevalidierung argumentieren. Vermeiden Sie es einfach, die gesamte Masse in ein Wenn zu packen.
quelle
Ich ziehe es vor, die redundante else-Anweisung wegzulassen. Wann immer ich es sehe (bei der Codeüberprüfung oder beim Refactoring), frage ich mich, ob der Autor den Kontrollfluss verstanden hat und ob möglicherweise ein Fehler im Code vorliegt.
Wenn der Autor der Meinung ist, dass die else-Anweisung notwendig ist und daher die Auswirkungen der return-Anweisung auf den Kontrollfluss nicht versteht, ist ein solches Unverständnis sicherlich eine Hauptursache für Fehler in dieser Funktion und im Allgemeinen.
quelle