是否有充分的理由说明在函数中只有一个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语句对我来说是一种非常可疑的实践。

其他回答

我通常支持多个return语句。它们是最容易阅读的。

在某些情况下,这并不好。有时从函数返回可能非常复杂。我记得有一种情况,所有函数都必须链接到多个不同的库。一个库期望返回值是错误/状态代码,而其他库则不期望。使用一个return语句可以节省时间。

我很惊讶没人提到goto。Goto并不是每个人都想让你相信的编程的祸害。如果必须在每个函数中只有一个return语句,请将它放在末尾,并根据需要使用gotos跳转到该return语句。绝对避免标记和箭头编程,它们既丑陋又运行缓慢。

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

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

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

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

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

作为指导原则,我投票支持单次返回。这有助于一个常见的代码清理处理…例如,看看下面的代码…

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语句是一个更好的实践?

是的,有:

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的指导方针显然也提倡单次退出。

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