是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?
或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?
是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?
或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?
当前回答
对于足够小的函数来说,多个出口点很好——也就是说,可以在一个屏幕长度上完整地查看函数。如果一个冗长的函数同样包含多个出口点,则表明该函数可以进一步分割。
也就是说,除非绝对必要,否则我避免使用多出口功能。在更复杂的函数中,由于一些模糊的行中出现的一些错误返回,我感到了错误的痛苦。
其他回答
函数中return语句越多,该方法的复杂性就越高。如果您发现自己想知道是否有太多的return语句,那么您可能需要问问自己,该函数中是否有太多的代码行。
但是,不是,一个/多个返回语句并没有错。在某些语言中,这是一种比其他语言(C)更好的实践(c++)。
我曾经使用过糟糕的编码标准,强迫你使用单一的退出路径,如果函数不是琐碎的,结果几乎总是非结构化的意大利面条——你最终会遇到许多中断和继续。
I lean towards using guard clauses to return early and otherwise exit at the end of a method. The single entry and exit rule has historical significance and was particularly helpful when dealing with legacy code that ran to 10 A4 pages for a single C++ method with multiple returns (and many defects). More recently, accepted good practice is to keep methods small which makes multiple exits less of an impedance to understanding. In the following Kronoz example copied from above, the question is what occurs in //Rest of code...?:
void string fooBar(string s, int? i) {
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;
}
我意识到这个例子有点做作,但我很想把foreach循环重构成一个LINQ语句,然后将其视为一个保护子句。同样,在一个人为的例子中,代码的意图并不明显,someFunction()可能会有一些其他副作用,或者结果可能会在代码的// Rest中使用....
if (string.IsNullOrEmpty(s) || i == null) return null;
if (someFunction(s, i).Any(r => !r.Passed)) return null;
给出以下重构函数:
void string fooBar(string s, int? i) {
if (string.IsNullOrEmpty(s) || i == null) return null;
if (someFunction(s, i).Any(r => !r.Passed)) return null;
// Rest of code...
return ret;
}
在一个没有副作用的函数中,没有理由有多个返回值,你应该用函数式的风格来编写它们。在有副作用的方法中,事情更有顺序(时间索引),因此您使用命令式风格编写,使用return语句作为停止执行的命令。
换句话说,如果可能的话,尽量采用这种风格
return a > 0 ?
positively(a):
negatively(a);
在这
if (a > 0)
return positively(a);
else
return negatively(a);
如果您发现自己编写了几层嵌套的条件,可能有一种方法可以重构它,例如使用谓词列表。如果您发现If和else在语法上相差很大,您可能希望将其分解为更小的函数。跨越超过一屏文本的条件块很难阅读。
没有适用于每一种语言的严格规则。像只有一个return语句这样的东西不会使你的代码好。但是好的代码将允许您以这种方式编写函数。
I always avoid multiple return statements. Even in small functions. Small functions can become larger, and tracking the multiple return paths makes it harder (to my small mind) to keep track of what is going on. A single return also makes debugging easier. I've seen people post that the only alternative to multiple return statements is a messy arrow of nested IF statements 10 levels deep. While I certain agree that such coding does occur, it isn't the only option. I wouldn't make the choice between a multiple return statements and a nest of IFs, I'd refactor it so you'd eliminate both. And that is how I code. The following code eliminates both issues and, in my mind, is very easy to read:
public string GetResult()
{
string rv = null;
bool okay = false;
okay = PerformTest(1);
if (okay)
{
okay = PerformTest(2);
}
if (okay)
{
okay = PerformTest(3);
}
if (okay)
{
okay = PerformTest(4);
};
if (okay)
{
okay = PerformTest(5);
}
if (okay)
{
rv = "All Tests Passed";
}
return rv;
}