是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?
或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?
是否有充分的理由说明在函数中只有一个return语句是一个更好的实践?
或者在逻辑上正确的情况下,可以从函数中返回,这意味着函数中可能有许多返回语句?
当前回答
有时出于性能考虑,这是必要的(我不想获取不同的缓存线,就像继续一样;有时)。
如果你不使用RAII分配资源(内存、文件描述符、锁等),那么多次返回很容易出错,而且肯定是重复的,因为释放需要手动执行多次,你必须仔细跟踪。
在这个例子中:
function()
{
HRESULT error = S_OK;
if(SUCCEEDED(Operation1()))
{
if(SUCCEEDED(Operation2()))
{
if(SUCCEEDED(Operation3()))
{
if(SUCCEEDED(Operation4()))
{
}
else
{
error = OPERATION4FAILED;
}
}
else
{
error = OPERATION3FAILED;
}
}
else
{
error = OPERATION2FAILED;
}
}
else
{
error = OPERATION1FAILED;
}
return error;
}
我会把它写成:
function() {
HRESULT error = OPERATION1FAILED;//assume failure
if(SUCCEEDED(Operation1())) {
error = OPERATION2FAILED;//assume failure
if(SUCCEEDED(Operation3())) {
error = OPERATION3FAILED;//assume failure
if(SUCCEEDED(Operation3())) {
error = OPERATION4FAILED; //assume failure
if(SUCCEEDED(Operation4())) {
error = S_OK;
}
}
}
}
return error;
}
这当然看起来更好。
这在手动资源释放的情况下尤其有用,因为在哪里和哪些释放是必要的是相当直接的。如下例所示:
function() {
HRESULT error = OPERATION1FAILED;//assume failure
if(SUCCEEDED(Operation1())) {
//allocate resource for op2;
char* const p2 = new char[1024];
error = OPERATION2FAILED;//assume failure
if(SUCCEEDED(Operation2(p2))) {
//allocate resource for op3;
char* const p3 = new char[1024];
error = OPERATION3FAILED;//assume failure
if(SUCCEEDED(Operation3(p3))) {
error = OPERATION4FAILED; //assume failure
if(SUCCEEDED(Operation4(p2,p3))) {
error = S_OK;
}
}
//free resource for op3;
delete [] p3;
}
//free resource for op2;
delete [] p2;
}
return error;
}
如果在没有RAII(忘记异常问题!)的情况下使用多个出口编写这段代码,则必须多次写入删除。如果你用}else{then 这有点难看。
但是RAII使得多个出口资源问题变得毫无意义。
其他回答
我认为在不同的情况下,不同的方法更好。例如,如果您应该在返回之前处理返回值,则应该有一个退出点。但在其他情况下,使用多次返回会更舒服。
一个音符。如果在某些情况下,你应该在返回之前处理返回值,但不是所有情况下,最好的解决方案(IMHO)是定义一个像ProcessVal这样的方法,并在返回之前调用它:
var retVal = new RetVal();
if(!someCondition)
return ProcessVal(retVal);
if(!anotherCondition)
return retVal;
我使用多个出口点使错误情况+处理+返回值尽可能接近。
所以必须测试条件a, b, c必须为真,你需要用不同的方式处理它们:
if (a is false) {
handle this situation (eg. report, log, message, etc.)
return some-err-code
}
if (b is false) {
handle this situation
return other-err-code
}
if (c is false) {
handle this situation
return yet-another-err-code
}
perform any action assured that a, b and c are ok.
a, b和c可能是不同的东西,比如a是输入参数检查,b是新分配内存的指针检查,c是检查参数a中的值。
你可以这样做,只实现一个返回语句-在开始时声明它,在结束时输出它-问题解决了:
$content = "";
$return = false;
if($content != "")
{
$return = true;
}
else
{
$return = false;
}
return $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;
}
使用单个出口点确实在调试中提供了优势,因为它允许您在函数的末尾设置单个断点,以查看实际将返回的值。