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

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


当前回答

作为嵌套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've seen it in coding standards for C++ that were a hang-over from C, as if you don't have RAII or other automatic memory management then you have to clean up for each return, which either means cut-and-paste of the clean-up or a goto (logically the same as 'finally' in managed languages), both of which are considered bad form. If your practices are to use smart pointers and collections in C++ or another automatic memory system, then there isn't a strong reason for it, and it become all about readability, and more of a judgement call.

我倾向于认为函数中间的return语句是不好的。您可以使用返回在函数的顶部构建一些保护子句,当然也可以告诉编译器在函数的末尾返回什么,但函数中间的返回很容易被忽略,并且会使函数更难解释。

我认为在不同的情况下,不同的方法更好。例如,如果您应该在返回之前处理返回值,则应该有一个退出点。但在其他情况下,使用多次返回会更舒服。

一个音符。如果在某些情况下,你应该在返回之前处理返回值,但不是所有情况下,最好的解决方案(IMHO)是定义一个像ProcessVal这样的方法,并在返回之前调用它:

var retVal = new RetVal();

if(!someCondition)
    return ProcessVal(retVal);

if(!anotherCondition)
   return retVal;

我曾经使用过糟糕的编码标准,强迫你使用单一的退出路径,如果函数不是琐碎的,结果几乎总是非结构化的意大利面条——你最终会遇到许多中断和继续。

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

是的,有:

The single exit point gives an excellent place to assert your post-conditions. Being able to put a debugger breakpoint on the one return at the end of the function is often useful. Fewer returns means less complexity. Linear code is generally simpler to understand. If trying to simplify a function to a single return causes complexity, then that's incentive to refactor to smaller, more general, easier-to-understand functions. If you're in a language without destructors or if you don't use RAII, then a single return reduces the number of places you have to clean up. Some languages require a single exit point (e.g., Pascal and Eiffel).

这个问题通常被提出为多个返回或深度嵌套的if语句之间的错误二分法。几乎总有第三种解决方案,它是线性的(没有深度嵌套),只有一个出口点。

更新:MISRA的指导方针显然也提倡单次退出。

需要澄清的是,我并不是说拥有多个回报总是错误的。但如果有其他等价的解决方案,有很多很好的理由选择单一回报的方案。