Ich habe immer von einer einzelnen Exit-Point-Funktion als schlechter Weg zum Codieren gehört, weil Sie an Lesbarkeit und Effizienz verlieren. Ich habe noch nie jemanden auf der anderen Seite streiten hören.
Ich dachte, das hätte etwas mit CS zu tun, aber diese Frage wurde bei cstheory stackexchange abgeschossen.
coding-style
Hex Bob-Omb
quelle
quelle
Antworten:
Es gibt verschiedene Denkrichtungen, und es kommt größtenteils auf die persönlichen Vorlieben an.
Zum einen ist es weniger verwirrend, wenn es nur einen einzigen Austrittspunkt gibt - Sie haben einen einzigen Pfad durch die Methode und wissen, wo Sie nach dem Ausgang suchen müssen. Auf der negativen Seite, wenn Sie Einrückungen verwenden, um die Verschachtelung darzustellen, wird Ihr Code massiv nach rechts eingerückt, und es wird sehr schwierig, allen verschachtelten Bereichen zu folgen.
Zum anderen können Sie die Voraussetzungen überprüfen und zu Beginn einer Methode frühzeitig beenden, sodass Sie im Hauptteil der Methode wissen, dass bestimmte Bedingungen erfüllt sind, ohne dass der gesamte Körper der Methode 5 Meilen nach rechts eingerückt ist. Dies minimiert normalerweise die Anzahl der Bereiche, über die Sie sich Sorgen machen müssen, was das Verfolgen von Code erheblich erleichtert.
Ein dritter ist, dass Sie jederzeit verlassen können. Früher war dies verwirrender, aber jetzt, da wir Syntax-Editoren und Compiler haben, die nicht erreichbaren Code erkennen, ist es viel einfacher, damit umzugehen.
Ich bin gerade im mittleren Lager. Das Erzwingen eines einzelnen Austrittspunkts ist meiner Meinung nach eine sinnlose oder sogar kontraproduktive Einschränkung, während das zufällige Verlassen einer Methode manchmal zu einer chaotischen, schwer zu befolgenden Logik führen kann, bei der es schwierig wird zu erkennen, ob ein bestimmtes Codebit vorhanden ist oder nicht hingerichtet. Durch das "Gating" Ihrer Methode ist es jedoch möglich, den Hauptteil der Methode erheblich zu vereinfachen.
quelle
singe exit
Paradigma durchgo to
Aussagen vermieden werden . Darüber hinaus hat man die Möglichkeit, eine Nachbearbeitung unter der lokalenError
Bezeichnung der Funktion durchzuführen , was mit mehrerenreturn
s unmöglich ist .Meine allgemeine Empfehlung lautet, dass return-Anweisungen, wenn dies praktikabel ist, entweder vor dem ersten Code mit Nebenwirkungen oder nach dem letzten Code mit Nebenwirkungen stehen sollten. Ich würde etwas in Betracht ziehen wie:
klarer als:
Wenn eine bestimmte Bedingung eine Funktion daran hindern sollte, etwas zu tun, ziehe ich es vor, an einer Stelle oberhalb des Punktes, an dem die Funktion etwas tun würde, frühzeitig aus der Funktion zurückzukehren. Sobald die Funktion Aktionen mit Nebenwirkungen durchgeführt hat, kehre ich lieber von unten zurück, um zu verdeutlichen, dass alle Nebenwirkungen behandelt werden müssen.
quelle
ok
Variablen, scheint mir der Single-Return-Ansatz zu sein. Darüber hinaus kann der if-else-Block einfach umgeschrieben werden in:return ok ? 0 : ERR_NOT_OK;
return
am Anfang einen Code vor allem, der alles macht. Wenn Sie den?:
Operator in separaten Zeilen schreiben, können viele IDEs leichter einen Debug-Haltepunkt an das nicht in Ordnung befindliche Szenario anhängen. Übrigens liegt der eigentliche Schlüssel zum "einzelnen Austrittspunkt" im Verständnis, dass es darauf ankommt, dass für jeden bestimmten Aufruf einer normalen Funktion der Austrittspunkt der Punkt unmittelbar nach dem Anruf ist . Programmierer halten das heutzutage für selbstverständlich, aber das war nicht immer so. In einigen seltenen Fällen muss Code möglicherweise ohne Stapelspeicher auskommen, was zu Funktionen führt ...Ein einziger Ein- und Ausstiegspunkt war das ursprüngliche Konzept der strukturierten Programmierung im Vergleich zur schrittweisen Spaghetti-Codierung. Es besteht die Überzeugung, dass mehrere Exit-Point-Funktionen mehr Code erfordern, da Sie die für Variablen zugewiesenen Speicherplätze ordnungsgemäß bereinigen müssen. Stellen Sie sich ein Szenario vor, in dem die Funktion Variablen (Ressourcen) zuweist und ein frühzeitiges Verlassen der Funktion ohne ordnungsgemäße Bereinigung zu Ressourcenlecks führen würde. Darüber hinaus würde das Erstellen einer Bereinigung vor jedem Exit viel redundanten Code erzeugen.
quelle
Bei fast allem kommt es auf die Bedürfnisse des Ergebnisses an. In "alten Zeiten" führte Spaghetti-Code mit mehreren Rückgabepunkten zu Speicherlecks, da Codierer, die diese Methode bevorzugten, normalerweise nicht gut bereinigten. Es gab auch Probleme mit einigen Compilern, die den Verweis auf die Rückgabevariable "verloren" haben, da der Stapel während der Rückgabe gelöscht wurde, wenn von einem verschachtelten Bereich zurückgekehrt wurde. Das allgemeinere Problem war der wiedereintretende Code, bei dem versucht wird, dass der aufrufende Status einer Funktion genau dem Rückgabestatus entspricht. Mutatoren von oop haben dies verletzt und das Konzept wurde zurückgestellt.
Es gibt Ergebnisse, insbesondere Kernel, die die Geschwindigkeit benötigen, die mehrere Austrittspunkte bieten. Diese Umgebungen verfügen normalerweise über ein eigenes Speicher- und Prozessmanagement, sodass das Risiko eines Lecks minimiert wird.
Persönlich möchte ich einen einzigen Austrittspunkt haben, da ich ihn häufig verwende, um einen Haltepunkt in die return-Anweisung einzufügen und eine Codeüberprüfung durchzuführen, wie der Code diese Lösung bestimmt hat. Ich könnte einfach zum Eingang gehen und durchgehen, was ich mit weitgehend verschachtelten und rekursiven Lösungen mache. Als Code-Reviewer erfordern mehrere Rückgaben in einer Funktion eine viel tiefere Analyse. Wenn Sie dies also tun, um die Implementierung zu beschleunigen, rauben Sie Peter aus, um Paul zu retten. Bei Codeüberprüfungen wird mehr Zeit benötigt, was die Annahme einer effizienten Implementierung ungültig macht.
- 2 Cent
Weitere Informationen finden Sie in diesem Dokument: NISTIR 5459
quelle
multiple returns in a function requires a much deeper analysis
nur wenn die Funktion bereits riesig ist (> 1 Bildschirm), sonst erleichtert es die AnalyseMeiner Ansicht nach ist der Rat, eine Funktion (oder eine andere Kontrollstruktur) nur an einem Punkt zu verlassen, häufig überverkauft. Zwei Gründe werden normalerweise angegeben, um nur an einem Punkt zu beenden:
Der zweite Grund ist subtil und hat einige Vorteile, insbesondere wenn die Funktion eine große Datenstruktur zurückgibt. Ich würde mir jedoch keine allzu großen Sorgen machen, außer ...
Wenn Sie ein Schüler sind, möchten Sie in Ihrer Klasse Bestnoten erzielen. Mach was der Instruktor bevorzugt. Er hat wahrscheinlich einen guten Grund aus seiner Sicht; Zumindest lernst du seine Perspektive. Das hat Wert an sich.
Viel Glück.
quelle
Früher war ich ein Verfechter des Single-Exit-Stils. Meine Argumentation kam hauptsächlich von Schmerzen ...
Single-Exit ist einfacher zu debuggen.
Angesichts der Techniken und Werkzeuge, über die wir heute verfügen, ist dies eine weitaus weniger vernünftige Position, da Unit-Tests und Protokollierung einen Single-Exit unnötig machen können. Das heißt, wenn Sie die Ausführung von Code in einem Debugger beobachten müssen, war es viel schwieriger, Code mit mehreren Exit-Punkten zu verstehen und damit zu arbeiten.
Dies traf insbesondere dann zu, wenn Sie Zuweisungen einwerfen mussten, um den Status zu überprüfen (in modernen Debuggern durch Überwachungsausdrücke ersetzt). Es war auch zu einfach, den Kontrollfluss so zu ändern, dass das Problem verborgen oder die Ausführung insgesamt unterbrochen wurde.
Single-Exit-Methoden waren im Debugger einfacher zu durchlaufen und leichter auseinander zu ziehen, ohne die Logik zu brechen.
quelle
Die Antwort ist sehr kontextabhängig. Wenn Sie eine grafische Benutzeroberfläche erstellen und eine Funktion haben, die APIs initialisiert und Fenster zu Beginn Ihres Hauptmenüs öffnet, ist sie voll von Aufrufen, die Fehler auslösen können, von denen jeder dazu führen würde, dass die Instanz des Programms geschlossen wird. Wenn Sie verschachtelte IF-Anweisungen verwenden und einrücken, kann Ihr Code schnell nach rechts verschoben werden. Die Rückkehr zu einem Fehler in jeder Phase ist möglicherweise besser und tatsächlich besser lesbar, während das Debuggen mit ein paar Flags im Code genauso einfach ist.
Wenn Sie jedoch unterschiedliche Bedingungen testen und je nach den Ergebnissen Ihrer Methode unterschiedliche Werte zurückgeben, ist es möglicherweise viel besser, einen einzigen Austrittspunkt zu haben. Ich habe in MATLAB an Bildverarbeitungsskripten gearbeitet, die sehr groß werden konnten. Mehrere Austrittspunkte können es äußerst schwierig machen, dem Code zu folgen. Switch-Anweisungen waren viel angemessener.
Das Beste, was Sie tun können, ist zu lernen, während Sie gehen. Wenn Sie Code für etwas schreiben, versuchen Sie, den Code anderer Leute zu finden und zu sehen, wie sie ihn implementieren. Entscheide, welche Bits du magst und welche nicht.
quelle
Wenn Sie das Gefühl haben, mehrere Austrittspunkte in einer Funktion zu benötigen, ist die Funktion zu groß und macht zu viel.
Ich würde empfehlen, das Kapitel über Funktionen in Robert C. Martins Buch Clean Code zu lesen.
Im Wesentlichen sollten Sie versuchen, Funktionen mit maximal 4 Codezeilen zu schreiben.
Einige Notizen aus Mike Longs Blog :
quelle