是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?
或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?
是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?
或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?
当前回答
这可能是一个不寻常的观点,但我认为任何相信多个return语句是有利的人都从未在只支持4个硬件断点的微处理器上使用过调试器。:-)
虽然“箭头代码”的问题是完全正确的,但当使用多个return语句时,一个问题似乎消失了,那就是在使用调试器的情况下。您没有一个方便的万能位置来放置断点,以保证您将看到退出,从而看到返回条件。
其他回答
作为指导原则,我投票支持单次返回。这有助于一个常见的代码清理处理…例如,看看下面的代码…
void ProcessMyFile (char *szFileName)
{
FILE *fp = NULL;
char *pbyBuffer = NULL:
do {
fp = fopen (szFileName, "r");
if (NULL == fp) {
break;
}
pbyBuffer = malloc (__SOME__SIZE___);
if (NULL == pbyBuffer) {
break;
}
/*** Do some processing with file ***/
} while (0);
if (pbyBuffer) {
free (pbyBuffer);
}
if (fp) {
fclose (fp);
}
}
我通常支持多个return语句。它们是最容易阅读的。
在某些情况下,这并不好。有时从函数返回可能非常复杂。我记得有一种情况,所有函数都必须链接到多个不同的库。一个库期望返回值是错误/状态代码,而其他库则不期望。使用一个return语句可以节省时间。
我很惊讶没人提到goto。Goto并不是每个人都想让你相信的编程的祸害。如果必须在每个函数中只有一个return语句,请将它放在末尾,并根据需要使用gotos跳转到该return语句。绝对避免标记和箭头编程,它们既丑陋又运行缓慢。
我可能会因此被讨厌,但理想情况下,我认为根本不应该有return语句,函数应该只返回它最后一个表达式,在完全理想的情况下,应该只包含一个。
所以不
function name(arg) {
if (arg.failure?)
return;
//code for non failure
}
而是
function name(arg) {
if (arg.failure?)
voidConstant
else {
//code for non failure
}
不是表达式的if语句和return语句对我来说是一种非常可疑的实践。
我认为在不同的情况下,不同的方法更好。例如,如果您应该在返回之前处理返回值,则应该有一个退出点。但在其他情况下,使用多次返回会更舒服。
一个音符。如果在某些情况下,你应该在返回之前处理返回值,但不是所有情况下,最好的解决方案(IMHO)是定义一个像ProcessVal这样的方法,并在返回之前调用它:
var retVal = new RetVal();
if(!someCondition)
return ProcessVal(retVal);
if(!anotherCondition)
return retVal;
我目前正在开发一个代码库,其中有两个人盲目地赞同“单点退出”理论,我可以告诉你,从经验来看,这是一个非常可怕的实践。这使得代码极其难以维护,我将向您展示原因。
根据“单点退出”理论,你不可避免地会得到这样的代码:
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条件和大括号都正确匹配。
这种方法使代码维护极其困难,而且容易出错。