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

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


当前回答

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

17.1返回

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

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

其他回答

使用单个出口点确实在调试中提供了优势,因为它允许您在函数的末尾设置单个断点,以查看实际将返回的值。

我目前正在开发一个代码库,其中有两个人盲目地赞同“单点退出”理论,我可以告诉你,从经验来看,这是一个非常可怕的实践。这使得代码极其难以维护,我将向您展示原因。

根据“单点退出”理论,你不可避免地会得到这样的代码:

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

这不仅使代码难以理解,而且以后还需要返回并在1和2之间添加一个操作。您必须缩进整个该死的函数,并确保所有if/else条件和大括号都正确匹配。

这种方法使代码维护极其困难,而且容易出错。

这主要是Fortran的遗留问题,在Fortran中,可以将多个语句标签传递给一个函数,这样函数就可以返回其中任何一个。

所以这种代码是完全有效的

       CALL SOMESUB(ARG1, 101, 102, 103)
C Some code
 101   CONTINUE
C Some more code
 102   CONTINUE
C Yet more code
 103   CONTINUE
C You get the general idea

但是被调用的函数决定了你的代码路径。有效率呢?可能。可维护的?不。

这就是该规则的来源(顺便说一下,一个函数没有多个入口点,这在fortran和汇编程序中是可能的,但在C中不可能)。

然而,它的措辞看起来像是可以应用到其他语言(关于多个入口点的那个不能应用到其他语言,所以它不是一个真正的程序)。所以这条规则被保留了下来,即使它指的是一个完全不同的问题,而且不适用。

对于更结构化的语言,需要放弃这个规则,或者至少考虑更多。当然,一个充满返回值的函数很难理解,但在开始时返回不是问题。在一些c++编译器中,如果你只从一个地方返回一个值,那么一个返回点可能会生成更好的代码。

但是最初的规则被误解了,被误用了。也不再相关了。

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.

一般来说,我尝试从一个函数中只有一个出口点。然而,有时这样做实际上会创建一个比必要的更复杂的函数体,在这种情况下,最好有多个出口点。它确实需要基于结果的复杂性进行“判断”,但目标应该是在不牺牲复杂性和可理解性的情况下尽可能减少出口点。