是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?
或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?
是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?
或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?
当前回答
使用单个出口点确实在调试中提供了优势,因为它允许您在函数的末尾设置单个断点,以查看实际将返回的值。
其他回答
我通常支持多个return语句。它们是最容易阅读的。
在某些情况下,这并不好。有时从函数返回可能非常复杂。我记得有一种情况,所有函数都必须链接到多个不同的库。一个库期望返回值是错误/状态代码,而其他库则不期望。使用一个return语句可以节省时间。
我很惊讶没人提到goto。Goto并不是每个人都想让你相信的编程的祸害。如果必须在每个函数中只有一个return语句,请将它放在末尾,并根据需要使用gotos跳转到该return语句。绝对避免标记和箭头编程,它们既丑陋又运行缓慢。
我经常在一个方法的开头有几个语句来返回“简单”的情况。例如,这个:
public void DoStuff(Foo foo)
{
if (foo != null)
{
...
}
}
... (恕我直言)可以像这样变得更具可读性:
public void DoStuff(Foo foo)
{
if (foo == null) return;
...
}
所以,是的,我认为从一个函数/方法中有多个“出口点”是很好的。
正如Kent Beck在《实现模式》中讨论保护子句时指出的那样,使一个例程具有单一的入口和出口点……
是为了防止可能的混淆 当你在许多地方跳来跳去 同一例程中的位置。这让 当应用到FORTRAN或 汇编语言程序 有大量的全球数据,甚至 理解哪些语句是 执行是一项艰苦的工作……使用小方法和大部分本地数据,它是不必要的保守。”
我发现用保护子句编写的函数要比一长串嵌套的if then else语句容易理解得多。
我认为在不同的情况下,不同的方法更好。例如,如果您应该在返回之前处理返回值,则应该有一个退出点。但在其他情况下,使用多次返回会更舒服。
一个音符。如果在某些情况下,你应该在返回之前处理返回值,但不是所有情况下,最好的解决方案(IMHO)是定义一个像ProcessVal这样的方法,并在返回之前调用它:
var retVal = new RetVal();
if(!someCondition)
return ProcessVal(retVal);
if(!anotherCondition)
return retVal;
如果你最终得到了很多返回值,那么你的代码可能有问题。否则,我同意有时能够从子例程的多个位置返回是很好的,特别是当它使代码更干净的时候。
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]
}
注意,这只是一个简单的例子