是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?
或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?
是否有充分的理由说明在函数中只有一个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),最好将它分解成几个较小的函数,每个函数都有一个退出点。
你可以这样做,只实现一个返回语句-在开始时声明它,在结束时输出它-问题解决了:
$content = "";
$return = false;
if($content != "")
{
$return = true;
}
else
{
$return = false;
}
return $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);
不,因为我们不再生活在20世纪70年代了。如果你的函数足够长以至于多次返回都是个问题,那么它就太长了。
(除了语言中有异常的任何多行函数都会有多个退出点这一事实。)
我强迫自己只使用一个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);
}
当然,它会更长,而且有点乱,但在以这种方式重构函数的过程中,我们已经
创建了许多可重用的函数, 使函数更具人类可读性,以及 函数的重点在于为什么值是正确的。