是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?
或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?
是否有充分的理由说明在函数中只有一个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);
}
}
其他回答
如果你最终得到了很多返回值,那么你的代码可能有问题。否则,我同意有时能够从子例程的多个位置返回是很好的,特别是当它使代码更干净的时候。
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]
}
注意,这只是一个简单的例子
由于错误处理,您已经隐式地拥有多个隐式返回语句,因此要处理它。
但是,就像编程中的典型情况一样,有支持和反对多次返回实践的例子。如果它能让代码更清晰,那就这样做。使用许多控制结构会有所帮助(例如case语句)。
我通常的策略是在函数的末尾只有一个return语句,除非通过添加更多的return语句来大大降低代码的复杂性。事实上,我是Eiffel的粉丝,它通过没有return语句强制执行唯一的返回规则(只有一个自动创建的'result'变量来放入结果)。
当然,在某些情况下,有多个返回值的代码比没有返回值的代码更清晰。有人可能会说,如果一个函数太复杂,没有多个return语句就无法理解,那么就需要更多的返工,但有时对这种事情采取务实的态度是好的。
在一个没有副作用的函数中,没有理由有多个返回值,你应该用函数式的风格来编写它们。在有副作用的方法中,事情更有顺序(时间索引),因此您使用命令式风格编写,使用return语句作为停止执行的命令。
换句话说,如果可能的话,尽量采用这种风格
return a > 0 ?
positively(a):
negatively(a);
在这
if (a > 0)
return positively(a);
else
return negatively(a);
如果您发现自己编写了几层嵌套的条件,可能有一种方法可以重构它,例如使用谓词列表。如果您发现If和else在语法上相差很大,您可能希望将其分解为更小的函数。跨越超过一屏文本的条件块很难阅读。
没有适用于每一种语言的严格规则。像只有一个return语句这样的东西不会使你的代码好。但是好的代码将允许您以这种方式编写函数。
我通常支持多个return语句。它们是最容易阅读的。
在某些情况下,这并不好。有时从函数返回可能非常复杂。我记得有一种情况,所有函数都必须链接到多个不同的库。一个库期望返回值是错误/状态代码,而其他库则不期望。使用一个return语句可以节省时间。
我很惊讶没人提到goto。Goto并不是每个人都想让你相信的编程的祸害。如果必须在每个函数中只有一个return语句,请将它放在末尾,并根据需要使用gotos跳转到该return语句。绝对避免标记和箭头编程,它们既丑陋又运行缓慢。