是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?

或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?


当前回答

没有人提到或引用代码完成,所以我就这么做。

17.1返回

尽量减少每个例程的返回次数。如果在底部阅读一个例程,你没有意识到它可能会返回到上面的某个地方,那么理解它就更难了。

在增强可读性时使用返回。在某些例程中,一旦知道了答案,就希望立即将其返回给调用例程。如果例程以不需要任何清理的方式定义,则不立即返回意味着必须编写更多代码。

其他回答

作为嵌套if的替代方法,有一种使用do/while(false)在任何地方爆发的方法:

    function()
    {
        HRESULT error = S_OK;

        do
        {
            if(!SUCCEEDED(Operation1()))
            {
                error = OPERATION1FAILED;
                break;
            }

            if(!SUCCEEDED(Operation2()))
            {
                error = OPERATION2FAILED;
                break;
            }

            if(!SUCCEEDED(Operation3()))
            {
                error = OPERATION3FAILED;
                break;
            }
            if(!SUCCEEDED(Operation4()))
            {
                error = OPERATION4FAILED;
                break;
            }
        } while (false);

        return error;
    }

这为您提供了一个出口点,允许您进行其他嵌套操作,但仍然不是真正的深层结构。如果你不喜欢成功,你可以做任何失败的事情。这类事情还允许您在任意两个其他检查之间添加其他代码,而无需重新缩进任何内容。

如果你真的疯了,整个If块也可以宏化。: D

    #define BREAKIFFAILED(x,y) if (!SUCCEEDED((x))) { error = (Y); break; }

    do
    {
        BREAKIFFAILED(Operation1(), OPERATION1FAILED)
        BREAKIFFAILED(Operation2(), OPERATION2FAILED)
        BREAKIFFAILED(Operation3(), OPERATION3FAILED)
        BREAKIFFAILED(Operation4(), OPERATION4FAILED)
    } while (false);

我想说的是,你应该有尽可能多的需要,或者任何使代码更干净的(如保护子句)。

我个人从来没有听过/见过任何“最佳实践”说你应该只有一个返回语句。

在大多数情况下,我倾向于根据逻辑路径尽快退出函数(保护子句就是一个很好的例子)。

I lean towards using guard clauses to return early and otherwise exit at the end of a method. The single entry and exit rule has historical significance and was particularly helpful when dealing with legacy code that ran to 10 A4 pages for a single C++ method with multiple returns (and many defects). More recently, accepted good practice is to keep methods small which makes multiple exits less of an impedance to understanding. In the following Kronoz example copied from above, the question is what occurs in //Rest of code...?:

void string fooBar(string s, int? i) {

  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;
}

我意识到这个例子有点做作,但我很想把foreach循环重构成一个LINQ语句,然后将其视为一个保护子句。同样,在一个人为的例子中,代码的意图并不明显,someFunction()可能会有一些其他副作用,或者结果可能会在代码的// Rest中使用....

if (string.IsNullOrEmpty(s) || i == null) return null;
if (someFunction(s, i).Any(r => !r.Passed)) return null;

给出以下重构函数:

void string fooBar(string s, int? i) {

  if (string.IsNullOrEmpty(s) || i == null) return null;
  if (someFunction(s, i).Any(r => !r.Passed)) return null;

  // Rest of code...

  return ret;
}

I always avoid multiple return statements. Even in small functions. Small functions can become larger, and tracking the multiple return paths makes it harder (to my small mind) to keep track of what is going on. A single return also makes debugging easier. I've seen people post that the only alternative to multiple return statements is a messy arrow of nested IF statements 10 levels deep. While I certain agree that such coding does occur, it isn't the only option. I wouldn't make the choice between a multiple return statements and a nest of IFs, I'd refactor it so you'd eliminate both. And that is how I code. The following code eliminates both issues and, in my mind, is very easy to read:

public string GetResult()
{
    string rv = null;
    bool okay = false;

    okay = PerformTest(1);

    if (okay)
    {
        okay = PerformTest(2);
    }

    if (okay)
    {
        okay = PerformTest(3);
    }

    if (okay)
    {
        okay = PerformTest(4);
    };

    if (okay)
    {
        okay = PerformTest(5);
    }

    if (okay)
    {
        rv = "All Tests Passed";
    }

    return rv;
}

没有人提到或引用代码完成,所以我就这么做。

17.1返回

尽量减少每个例程的返回次数。如果在底部阅读一个例程,你没有意识到它可能会返回到上面的某个地方,那么理解它就更难了。

在增强可读性时使用返回。在某些例程中,一旦知道了答案,就希望立即将其返回给调用例程。如果例程以不需要任何清理的方式定义,则不立即返回意味着必须编写更多代码。