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

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


当前回答

我强迫自己只使用一个return语句,因为在某种意义上它会产生代码气味。让我解释一下:

function isCorrect($param1, $param2, $param3) {
    $toret = false;
    if ($param1 != $param2) {
        if ($param1 == ($param3 * 2)) {
            if ($param2 == ($param3 / 3)) {
                $toret = true;
            } else {
                $error = 'Error 3';
            }
        } else {
            $error = 'Error 2';
        }
    } else {
        $error = 'Error 1';
    }
    return $toret;
}

(条件是任意的…)

条件越多,函数越大,读取起来就越困难。因此,如果您熟悉代码气味,您就会意识到它,并想要重构代码。两种可能的解决方案是:

多的回报 重构为单独的函数

多的回报

function isCorrect($param1, $param2, $param3) {
    if ($param1 == $param2)       { $error = 'Error 1'; return false; }
    if ($param1 != ($param3 * 2)) { $error = 'Error 2'; return false; }
    if ($param2 != ($param3 / 3)) { $error = 'Error 3'; return false; }
    return true;
}

单独的功能

function isEqual($param1, $param2) {
    return $param1 == $param2;
}

function isDouble($param1, $param2) {
    return $param1 == ($param2 * 2);
}

function isThird($param1, $param2) {
    return $param1 == ($param2 / 3);
}

function isCorrect($param1, $param2, $param3) {
    return !isEqual($param1, $param2)
        && isDouble($param1, $param3)
        && isThird($param2, $param3);
}

当然,它会更长,而且有点乱,但在以这种方式重构函数的过程中,我们已经

创建了许多可重用的函数, 使函数更具人类可读性,以及 函数的重点在于为什么值是正确的。

其他回答

在其他条件相同的情况下,单一出口点可以显著提高代码的可读性。 但有一个问题:流行的结构

resulttype res;
if if if...
return res;

是假的,“res=”不比“return”好多少。它只有一个return语句,但函数实际结束的地方有多个点。

如果你的函数有多个返回值(或“res=”s),最好将它分解成几个较小的函数,每个函数都有一个退出点。

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

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

17.1返回

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

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

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

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

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

拥有多个出口点本质上与使用GOTO是一样的。这是不是件坏事取决于你对迅猛龙的看法。