779 Stimmen

Sollte eine Funktion nur eine Rückgabeanweisung haben?

Gibt es gute Gründe, warum es besser ist, nur eine Rückgabeanweisung in einer Funktion zu haben?

Oder ist es in Ordnung, aus einer Funktion zurückzukehren, sobald dies logisch korrekt ist, d.h. es kann viele Return-Anweisungen in der Funktion geben?

25 Stimmen

Ich stimme nicht zu, dass die Frage sprachenfeindlich ist. Bei einigen Sprachen ist die Mehrfachrückgabe natürlicher und bequemer als bei anderen. Ich würde mich eher über frühe Rückgaben in einer C-Funktion beschweren als in einer C++-Funktion, die RAII verwendet.

3 Stimmen

Diese Frage ist eng damit verbunden und enthält ausgezeichnete Antworten: programmers.stackexchange.com/questions/118703/

0 Stimmen

Sprachunabhängig? Erklären Sie jemandem, der eine funktionale Sprache verwendet, dass er einen Return pro Funktion verwenden muss :p

740voto

Matt Hamilton Punkte 193704

Ich habe oft mehrere Anweisungen am Anfang einer Methode, um für "einfache" Situationen zurückzukehren. Zum Beispiel dies:

public void DoStuff(Foo foo)
{
    if (foo != null)
    {
        ...
    }
}

... kann (IMHO) auf diese Weise lesbarer gemacht werden:

public void DoStuff(Foo foo)
{
    if (foo == null) return;

    ...
}

Also ja, ich denke, es ist in Ordnung, mehrere "Ausstiegspunkte" aus einer Funktion/Methode zu haben.

0 Stimmen

Ein gutes Argument. Dies würde in gewisser Weise einen Vertragsstil fördern, bei dem die Bedingungen im Vorfeld geltend gemacht und geprüft werden.

83 Stimmen

Einverstanden. Obwohl mehrere Exit-Punkte aus dem Ruder laufen können, halte ich es auf jeden Fall für besser, als die gesamte Funktion in einen IF-Block zu packen. Verwenden Sie return so oft, wie es sinnvoll ist, um Ihren Code lesbar zu halten.

172 Stimmen

Dies wird in Fowlers Refactoring als "Guard Statement" bezeichnet.

354voto

Chris S Punkte 63542

Niemand hat erwähnt oder zitiert Code vollständig also werde ich es tun.

17.1 Rückgabe

Minimieren Sie die Anzahl der Rückgaben in jeder Routine . Es ist schwieriger, eine Routine zu verstehen, wenn man sie am Ende liest und nicht weiß, dass sie irgendwo oben zurückkommt.

Verwenden Sie eine return wenn es die Lesbarkeit verbessert . In bestimmten Routinen möchten Sie die Antwort, sobald Sie sie kennen, sofort an die aufrufende Routine zurückgeben. Wenn die Routine so definiert ist, dass sie keine Aufräumarbeiten erfordert, bedeutet eine nicht sofortige Rückgabe, dass Sie mehr Code schreiben müssen.

64 Stimmen

+1 für die Nuance von "minimieren", aber nicht verbieten, mehrere Rückgaben.

13 Stimmen

"schwieriger zu verstehen" ist sehr subjektiv, vor allem, wenn der Autor keine empirischen Beweise liefert, um die allgemeine Behauptung zu untermauern... eine einzelne Variable zu haben, die an vielen bedingten Stellen im Code für die abschließende Rückgabeanweisung gesetzt werden muss, ist gleichbedeutend mit "sich der Möglichkeit nicht bewusst, dass die Variable irgendwo oben in der Funktion zugewiesen wurde!

26 Stimmen

Ich persönlich bevorzuge eine frühzeitige Rückkehr, wenn dies möglich ist. Und warum? Nun, wenn Sie das Schlüsselwort "Return" für einen bestimmten Fall sehen, wissen Sie sofort: "Ich bin fertig" - Sie müssen nicht weiter lesen, um herauszufinden, was, wenn überhaupt, danach passiert.

229voto

ljs Punkte 35909

Ich würde sagen, dass es äußerst unklug wäre, sich willkürlich gegen mehrere Ausstiegspunkte zu entscheiden, da ich die Technik in der Praxis als nützlich empfunden habe immer und immer wieder Ich habe in der Tat oft Überarbeitung des bestehenden Codes der Übersichtlichkeit halber auf mehrere Ausstiegspunkte. Wir können die beiden Ansätze folgendermaßen vergleichen:-

string fooBar(string s, int? i) {
  string ret = "";
  if(!string.IsNullOrEmpty(s) && i != null) {
    var res = someFunction(s, i);

    bool passed = true;
    foreach(var r in res) {
      if(!r.Passed) {
        passed = false;
        break;
      }
    }

    if(passed) {
      // Rest of code...
    }
  }

  return ret;
}

Vergleichen Sie dies mit dem Code, bei dem mehrere Ausstiegspunkte sont erlaubt:-

string fooBar(string s, int? i) {
  var ret = "";
  if(string.IsNullOrEmpty(s) || i == null) return null;

  var res = someFunction(s, i);

  foreach(var r in res) {
      if(!r.Passed) return null;
  }

  // Rest of code...

  return ret;
}

Ich denke, letzteres ist wesentlich klarer. Soweit ich das beurteilen kann, ist die Kritik an mehreren Ausstiegspunkten heutzutage eine ziemlich archaische Sichtweise.

12 Stimmen

Klarheit liegt im Auge des Betrachters - ich betrachte eine Funktion und suche einen Anfang, eine Mitte und ein Ende. Wenn die Funktion klein ist, ist das in Ordnung - aber wenn man versucht, herauszufinden, warum etwas kaputt ist, und der "Rest des Codes" sich als nicht trivial herausstellt, kann man Ewigkeiten damit verbringen, zu suchen, warum ret ist

0 Stimmen

Selbst in Ihrem ersten Beispielcode haben Sie einen frühen Rücklauf (für die foreach-Schleife). Natürlich ist das Design Ihres Iterators möglicherweise nicht hilfreich.

0 Stimmen

@Murph - Sie würden merken, dass der Rest des Codes nicht läuft, weil die Eingabe nicht den Anforderungen entspricht... @Tom - Ähm, wie kann das eine 'frühe Rückkehr' sein?!

191voto

17 of 26 Punkte 26635

Ich arbeite derzeit an einer Codebasis, bei der zwei der daran arbeitenden Personen blindlings der "Single Point of Exit"-Theorie anhängen, und ich kann Ihnen aus Erfahrung sagen, dass dies eine furchtbare Praxis ist. Es macht den Code extrem schwer zu pflegen und ich werde Ihnen zeigen, warum.

Mit der "Single Point of Exit"-Theorie landet man unweigerlich bei einem Code, der wie folgt aussieht:

function()
{
    HRESULT error = S_OK;

    if(SUCCEEDED(Operation1()))
    {
        if(SUCCEEDED(Operation2()))
        {
            if(SUCCEEDED(Operation3()))
            {
                if(SUCCEEDED(Operation4()))
                {
                }
                else
                {
                    error = OPERATION4FAILED;
                }
            }
            else
            {
                error = OPERATION3FAILED;
            }
        }
        else
        {
            error = OPERATION2FAILED;
        }
    }
    else
    {
        error = OPERATION1FAILED;
    }

    return error;
}

Das macht den Code nicht nur sehr unübersichtlich, sondern man muss auch später noch einmal zurückgehen und eine Operation zwischen 1 und 2 einfügen. Sie müssen fast die gesamte Funktion einrücken, und viel Glück dabei, alle if/else-Bedingungen und geschweiften Klammern richtig zu platzieren.

Diese Methode macht die Codepflege extrem schwierig und fehleranfällig.

1 Stimmen

Oder Sie könnten einfach eine Liste von Operationen haben, die den ersten Fehler aus der Anwendung jeder Operation in der Liste nacheinander zurückgibt.

0 Stimmen

Zum Glück kann ein guter Editor (in meinem Fall VIM) den gesamten Code auf Knopfdruck neu formatieren.

1 Stimmen

Ähm, ich bin nicht der Meinung, dass es schwer zu verstehen ist, es ist eigentlich sehr einfach zu verstehen, weil es einen logischen Ablauf gibt. Wartung? Sir braucht eine bessere IDE.

72voto

Chris de Vries Punkte 55383

Strukturierte Programmierung besagt, dass man immer nur eine Return-Anweisung pro Funktion haben sollte. Damit soll die Komplexität begrenzt werden. Viele Leute wie Martin Fowler argumentieren, dass es einfacher ist, Funktionen mit mehreren Rückgabeanweisungen zu schreiben. Er präsentiert dieses Argument in dem Klassiker Refaktorierung Buch, das er geschrieben hat. Das funktioniert gut, wenn man seine anderen Ratschläge befolgt und kleine Funktionen schreibt. Ich stimme dieser Sichtweise zu, und nur strenge Puristen der strukturierten Programmierung halten sich an einzelne Rückgabeanweisungen pro Funktion.

44 Stimmen

Die strukturierte Programmierung sagt gar nichts aus. Einige (aber nicht alle) Leute, die sich selbst als Verfechter der strukturierten Programmierung bezeichnen, sagen das.

15 Stimmen

"Das funktioniert gut, wenn Sie seinen anderen Rat befolgen und kleine Funktionen schreiben." Dies ist der wichtigste Punkt. Kleine Funktionen brauchen selten viele Rückgabestellen.

6 Stimmen

@wnoise +1 für den Kommentar, so wahr. Alles, was "structude programming" sagt, ist, verwenden Sie nicht GOTO.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X