是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?
或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?
是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?
或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?
当前回答
我想说,武断地决定不使用多个出口点是非常不明智的,因为我发现这种技术在实践中一次又一次地有用,事实上,为了清晰起见,我经常将现有的代码重构为多个出口点。我们可以这样比较这两种方法:-
string fooBar(string s, int? i) {
string ret = "";
if(!string.IsNullOrEmpty(s) && i != null) {
var res = someFunction(s, i);
bool passed = true;
foreach(var r in res) {
if(!r.Passed) {
passed = false;
break;
}
}
if(passed) {
// Rest of code...
}
}
return ret;
}
将此与允许多个出口点的代码进行比较
string fooBar(string s, int? i) {
var ret = "";
if(string.IsNullOrEmpty(s) || i == null) return null;
var res = someFunction(s, i);
foreach(var r in res) {
if(!r.Passed) return null;
}
// Rest of code...
return ret;
}
我认为后者要清楚得多。据我所知,现在对多个退出点的批评是一种相当过时的观点。
其他回答
由于错误处理,您已经隐式地拥有多个隐式返回语句,因此要处理它。
但是,就像编程中的典型情况一样,有支持和反对多次返回实践的例子。如果它能让代码更清晰,那就这样做。使用许多控制结构会有所帮助(例如case语句)。
我想说的是,你应该有尽可能多的需要,或者任何使代码更干净的(如保护子句)。
我个人从来没有听过/见过任何“最佳实践”说你应该只有一个返回语句。
在大多数情况下,我倾向于根据逻辑路径尽快退出函数(保护子句就是一个很好的例子)。
我能想到的一个很好的理由是代码维护:您有一个单一的退出点。如果你想改变结果的格式,…,它的实现要简单得多。此外,为了调试,你可以在那里插入一个断点:)
话虽如此,我曾经不得不在一个库中工作,那里的编码标准强制要求“每个函数一个返回语句”,我发现这相当困难。我写了很多数值计算代码,经常有“特殊情况”,所以代码最终很难跟上……
我更喜欢一个return语句。一个尚未指出的原因是,一些重构工具在单点退出时工作得更好,例如Eclipse JDT提取/内联方法。
作为指导原则,我投票支持单次返回。这有助于一个常见的代码清理处理…例如,看看下面的代码…
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);
}
}