我的个人做法如下:
- 我不喜欢带有多个退出点的函数,我发现很难维护和遵循它们,代码修改有时会破坏内部逻辑,因为它本质上有点草率。当它是复杂的计算时,我会在开始处创建一个返回值,并在结束时返回它。这迫使我仔细遵循每个if-else,switch等路径,在正确的位置正确设置该值。我还花了一些时间来决定是设置默认返回值还是在开始时将其保留为未初始化状态。当逻辑或返回值类型或含义更改时,此方法也有帮助。
例如:
public bool myFunction()
{
// First parameter loading
String myString = getString();
// Location of "quick exits", see the second example
// ...
// declaration of external resources that MUST be released whatever happens
// ...
// the return variable (should think about giving it a default value or not)
// if you have no default value, declare it final! You will get compiler
// error when you try to set it multiple times or leave uninitialized!
bool didSomething = false;
try {
if (myString != null)
{
myString = "Name " + myString;
// Do something more here...
didSomething = true;
} else {
// get other parameters and data
if ( other conditions apply ) {
// do something else
didSomething = true;
}
}
// Edit: previously forgot the most important advantage of this version
// *** HOUSEKEEPING!!! ***
} finally {
// this is the common place to release all resources, reset all state variables
// Yes, if you use try-finally, you will get here from any internal returns too.
// As I said, it is only my taste that I like to have one, straightforward path
// leading here, and this works even if you don't use the try-finally version.
}
return didSomething;
}
- 唯一的例外:开始时“快速退出”(或在极少数情况下,在过程内部)。如果实际的计算逻辑不能处理输入参数和内部状态的某种组合,或者在不运行算法的情况下提供简单的解决方案,则将所有代码封装在(有时很深)if块中无济于事。这是一个“异常状态”,不是核心逻辑的一部分,因此,我必须在检测到后立即退出计算。在这种情况下,没有其他分支,在正常情况下,执行将继续进行。(当然,通过抛出异常可以更好地表达“例外状态”,但有时这是一种过大的杀伤力。)
例如:
public bool myFunction()
{
String myString = getString();
if (null == myString)
{
// there is nothing to do if myString is null
return false;
}
myString = "Name " + myString;
// Do something more here...
// not using return value variable now, because the operation is straightforward.
// if the operation is complex, use the variable as the previous example.
return true;
}
当计算需要您必须释放的外部资源,或者要求您在退出函数之前必须重置时,“一个出口”规则也将提供帮助。有时,它们会在以后的开发过程中添加。由于算法内部有多个出口,因此很难正确地扩展所有分支。(而且,如果可能发生异常,则释放/重置也应放在finally块中,以避免在极少数例外情况下产生副作用……)。
您的案例似乎属于“在实际工作之前迅速退出”类别,我将其写为您的示例2版本。