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

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


当前回答

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

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

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

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

其他回答

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.

使用单一出口点可以降低圈复杂度,因此,从理论上讲,可以降低在修改代码时引入错误的可能性。然而,实践往往表明需要更务实的方法。因此,我倾向于只有一个出口点,但如果可读性更好,允许我的代码有多个出口点。

如果你最终得到了很多返回值,那么你的代码可能有问题。否则,我同意有时能够从子例程的多个位置返回是很好的,特别是当它使代码更干净的时候。

Perl 6:坏例子

sub Int_to_String( Int i ){
  given( i ){
    when 0 { return "zero" }
    when 1 { return "one" }
    when 2 { return "two" }
    when 3 { return "three" }
    when 4 { return "four" }
    ...
    default { return undef }
  }
}

这样写会更好吗

Perl 6:好例子

@Int_to_String = qw{
  zero
  one
  two
  three
  four
  ...
}
sub Int_to_String( Int i ){
  return undef if i < 0;
  return undef unless i < @Int_to_String.length;
  return @Int_to_String[i]
}

注意,这只是一个简单的例子

我经常在一个方法的开头有几个语句来返回“简单”的情况。例如,这个:

public void DoStuff(Foo foo)
{
    if (foo != null)
    {
        ...
    }
}

... (恕我直言)可以像这样变得更具可读性:

public void DoStuff(Foo foo)
{
    if (foo == null) return;

    ...
}

所以,是的,我认为从一个函数/方法中有多个“出口点”是很好的。

我认为在不同的情况下,不同的方法更好。例如,如果您应该在返回之前处理返回值,则应该有一个退出点。但在其他情况下,使用多次返回会更舒服。

一个音符。如果在某些情况下,你应该在返回之前处理返回值,但不是所有情况下,最好的解决方案(IMHO)是定义一个像ProcessVal这样的方法,并在返回之前调用它:

var retVal = new RetVal();

if(!someCondition)
    return ProcessVal(retVal);

if(!anotherCondition)
   return retVal;