我是否应该使用return/continue语句而不是if-else?

时间:2022-09-02 14:52:28

In C, C++ and C# when using a condition inside a function or loop statement it's possible to use a continue or return statement as early as possible and get rid of the else branch of an if-else statement. For example:

在C、c++和c#中,当在函数或循环语句中使用条件时,可以尽早使用continue或return语句,并删除if-else语句的else分支。例如:

while( loopCondition ) {
    if( innerCondition ) {
        //do some stuff
    } else {
        //do other stuff
    }
}

becomes

就变成了

 while( loopCondition ) {
    if( innerCondition ) {
        //do some stuff
        continue;
    }
    //do other stuff
}

and

void function() {
    if( condition ) {
        //do some stuff
    } else {
        //do other stuff
    }
}

becomes

就变成了

void function() {
    if( condition ) {
        //do some stuff
        return;
    }
    //do other stuff
}

The "after" variant may be more readable if the if-else branches are long because this alteration eliminates indenting for the else branch.

如果if-else分支比较长,“after”变体的可读性可能会更好,因为这种更改消除了else分支的缩进。

Is such using of return/continue a good idea? Are there any possible maintenance or readability problems?

这样使用return/continue是一个好主意吗?是否存在可能的维护或可读性问题?

13 个解决方案

#1


12  

The compiler will almost certainly generate the same code. Even if it didn't, the difference will be probably irrelevant. Hence, the relevant argument is certainly how people would read it.

编译器几乎肯定会生成相同的代码。即使没有,这种差异也可能无关紧要。因此,相关的论点当然是人们如何解读它。

Therefore the question is how similar "//do some stuff" and "do other stuff" are. If they are conceptually similar, use if/else. If they're conceptually different, use continue/return.

因此,问题是“//做一些事情”和“做其他事情”有多相似。如果它们在概念上相似,则使用If /else。如果它们在概念上不同,则使用continue/return。

#2


29  

My personal approach of choosing one is that if the body of the if part is very short (3 or 4 lines maximum), it makes sense to use the return/continue variant. If the body is long, it's harder to keep track of the control flow so I choose the else version.

我个人的选择方法是,如果if部分的主体非常短(最多3或4行),那么使用return/continue变量是有意义的。如果主体很长,就很难跟踪控制流,所以我选择了else版本。

As a result, normally, this approach limits the usage of return/continue style to skip some data and avoid further processing rather than process this using one of the following methods (which is better suited by if/else).

因此,通常,这种方法限制使用return/continue样式来跳过一些数据,避免进一步处理,而不是使用以下方法之一(if/else更适合这种方法)进行处理。

#3


12  

It depends a little on how long the branches are. The use of return/continue that you describe is good if the initial if check is short, and the body is long. If both if and else parts are long, I would extract them to separate functions.

这取决于树枝的长度。如果初始的if检查是短的,并且主体是长的,那么您描述的return/continue的使用是很好的。如果If和else部分都很长,我会将它们提取为独立的函数。

I recommend reading Code Complete, it discusses things like this a lot.

我推荐阅读完整的代码,它经常讨论这样的事情。

#4


11  

The code would be more readable if termination criteria are handled first. I always prefer, checking for conditions that require a break or return rather than those that would need lengthy code execution. I prefer:

如果首先处理终止条件,那么代码将更具可读性。我总是喜欢检查需要中断或返回的条件,而不是需要长时间代码执行的条件。我喜欢:

 if (termination condn) 
      return;
 // code 
 // code

to

if (success condn)
{
  // code
  // code
}
else
 return;

This makes reading and understanding the code easier.

这使得阅读和理解代码更加容易。

#5


6  

The glib answer is that it all depends.

巧妙的回答是,这要看情况而定。

My general feeling is that if condition is a rare, guard (e.g. check for null) or error condition then I tend to use return or continue

我的一般感觉是,如果条件是罕见的,保护(例如检查null)或错误条件,那么我倾向于使用return或continue

If it's an expected case then I tend to use your first approach.

如果这是预期的情况,我倾向于使用你的第一种方法。

Notice, however, that I said "tend". The boundary between these to conditions is vague and subject to change depending on the project and who I'm working with.

注意,我说的是“倾向”。它们与条件之间的界限是模糊的,可能会根据项目和我的合作伙伴而改变。

#6


4  

I usually prefer

我通常喜欢

while( loopCondition ) {
    if( innerCondition ) {
        DoStuff();
    } else {
        DoOtherStuff(); 
    }
}

continue can be hard to follow if the length of DoStuff passed the 1-2 line threshold (and its fairly easy to miss the intention). This seems like a good opportunity to refactor the logic into some smaller methods.

如果DoStuff的长度超过了1-2行阈值(而且很容易忽略意图),则很难跟踪continue。这似乎是一个很好的机会,可以将逻辑重构到一些更小的方法中。

#7


4  

Do not sacrifice readability for premature optimization.

不要为了过早的优化而牺牲可读性。

For example:

例如:

void function() {
    if( condition ) {
        //do some stuff
    } else {
        //do other stuff
    }
}

is in most cases binary equivalent to

在大多数情况下,二进制等于?

void function() {
    if( condition ) {
        //do some stuff
        return;
    }
    //do other stuff
}

(i.e. the resulting code is probably the same). But the readability of the former is much better, because you can clearly see that the code will to either X or Y.

(即产生的代码可能是相同的)。但是前者的可读性要好得多,因为您可以清楚地看到代码将指向X或Y。

#8


3  

1) Input or object state validation. Following code:

1)输入或对象状态验证。下面的代码:

void function() {
    if( condition ) {
        //do some stuff
        return;
    }
    //do other stuff
}

is good when the condition is some requirement for function to work. It's a stage of input validation or object state validation. It then feels right to use return immediately to emphasis, that function did not run at all.

当条件是对工作的一些要求时是好的。它是输入验证或对象状态验证的阶段。然后感觉应该立即使用return来强调,这个函数根本没有运行。

2) Multistage processing. While/continue is good when the loop pops elements from some collection and processes them in multistage manner:

2)多级处理。当循环从某些集合中取出元素并以多阶段方式处理时,/continue是好的:

while(foo = bar.getNext()) {
   if(foo.empty())
       continue;
   if(foo.alreadyProcessed())
       continue;
   // Can we take a shortcut?
   if(foo.tryProcessThingsYourself())
       continue;
   int baz = foo.getBaz();
   if(baz < 0) {
       int qux = foo.getQux();
       if(qux < 0) {
         // Error - go to next element
         continue;
       }
   }
   // Finally -- do the actual processing
   baz = baz * 2;
   foo.setBaz(baz);
}

The example shows how natural it is to use continue in scenario when series of multistage processing is done, when each processing can be interrupted by various conditions in various places.

该示例展示了在执行一系列多阶段处理时,当每个处理可以被不同地方的不同条件中断时,在场景中使用continue是多么自然。

Notice: plinth posted real-life example, which follows what 2) says.

注意:plinth贴出了现实生活中的例子,它遵循了2)所说的。

3) General rule. I use continue and return when it corresponds with fact that something has been interrupted. I use else, when the else is part of actual processing.

3)一般规则。我使用continue和return,当它与某事被中断相对应时。当else是实际处理的一部分时,我使用else。

#9


2  

One possible maintenance issue is that if a function has multiple returns, then it is harder to stick a breakpoint or tracing at the return when debugging. This is only rarely an issue, but when you do miss a return point it's a pain. I don't think it matters so much for continue in loops, since the loop condition and the top of the loop are both still unique.

一个可能的维护问题是,如果一个函数有多个返回,那么在调试时很难在返回中插入断点或跟踪。这很少是一个问题,但是当你错过一个返回点时,这是一种痛苦。我不认为它在循环中很重要,因为循环条件和循环的顶部都是唯一的。

Aside from that: what everyone else says. Do what's most readable, which depends on the relative length, importance, and likelihood of "some stuff" and "other stuff". The shorter, more trivial, and more unlikely a case is, the less disturbing it is for it to have special-case control flow.

除此之外:别人怎么说。做最易读的事情,这取决于“一些东西”和“其他东西”的相对长度、重要性和可能性。一个案例越短,越简单,越不可能发生,越不令人不安的是它有特殊情况控制流程。

#10


2  

as other people said, only use return/continue if things are short.

正如其他人所说,只有在事情很短的时候才使用return/continue。

Personally i only use continue if it is possible to write on one line like:

我个人只会继续使用,如果可以在一行上写:

while( loopCondition ) {
    if( innerCondition ) continue;

    //do other stuff
}

If it's not possible to write it like this without code getting ugly, then if / else.

如果不让代码变得难看就不能这样写,那么If / else。

#11


2  

For grins, I did a search across my company's codebase for "continue;" just to get an idea of where it's being used. We use if 695 times across 59 projects in one solution, roughly 1500 source files.

对于grins,我在我的公司的代码库中搜索了“continue”,只是想知道它在哪里被使用。我们在一个解决方案中使用了695次,在一个解决方案中使用了大约1500个源文件。

The main ways I see them being used are as a quick filter:

我看到他们被使用的主要方式是作为一个快速过滤器:

foreach (Frobozz bar in foo) {
    if (QuickFilterExclude(bar))
        continue;
    // extensive processing
}

A recovery from an expected exception:

从预期的异常中恢复:

foreach (Frobozz bar in foo) {
    Baz result = new Baz(kDefaultConfiguration);
    try {
        Baz remoteResult = boo.GetConfiguration();
    }
    catch (RemoteConnectionException) {
        continue;
    }
    result.Merge(remoteResult);
    ReportResult(result);
}

And finally in state machinery.

最后是国家机器。

#12


1  

I generally use the if-return method when jumping out of a method or loop because there is nothing to be done.

当跳出一个方法或循环时,我通常使用if-return方法,因为没有什么要做的。

If the body is longer because substantial work is being done, I suggest using if-else and maybe using #region to give blocks a sensible name and have them easily collapsable for people to study the control flow. That or make separate methods :)

如果主体较长,因为正在进行大量工作,我建议使用If -else,或者使用#region给块一个合理的名称,使它们易于折叠,以便人们研究控制流。或单独制作方法:)

#13


0  

I had the following in my code:

我的代码如下:

    while(){
      boolean intersect = doesIntersect(interval_1,interval_2);
      if(!intersect){
         array.add(interval_2);
         if(// another condition){
            // Do some thing here
         }
         continue;
      }
      // other stuff to do if intersect
    }

Was confusing whether I should use continue there or use else but I decided that the inner if condition might make the else not well readable, so I used continue.

我不知道我应该用continue还是用else,但是我觉得内部if条件可能会让else不太好读,所以我用continue。

I think readability is what matters!

我认为可读性才是最重要的!

#1


12  

The compiler will almost certainly generate the same code. Even if it didn't, the difference will be probably irrelevant. Hence, the relevant argument is certainly how people would read it.

编译器几乎肯定会生成相同的代码。即使没有,这种差异也可能无关紧要。因此,相关的论点当然是人们如何解读它。

Therefore the question is how similar "//do some stuff" and "do other stuff" are. If they are conceptually similar, use if/else. If they're conceptually different, use continue/return.

因此,问题是“//做一些事情”和“做其他事情”有多相似。如果它们在概念上相似,则使用If /else。如果它们在概念上不同,则使用continue/return。

#2


29  

My personal approach of choosing one is that if the body of the if part is very short (3 or 4 lines maximum), it makes sense to use the return/continue variant. If the body is long, it's harder to keep track of the control flow so I choose the else version.

我个人的选择方法是,如果if部分的主体非常短(最多3或4行),那么使用return/continue变量是有意义的。如果主体很长,就很难跟踪控制流,所以我选择了else版本。

As a result, normally, this approach limits the usage of return/continue style to skip some data and avoid further processing rather than process this using one of the following methods (which is better suited by if/else).

因此,通常,这种方法限制使用return/continue样式来跳过一些数据,避免进一步处理,而不是使用以下方法之一(if/else更适合这种方法)进行处理。

#3


12  

It depends a little on how long the branches are. The use of return/continue that you describe is good if the initial if check is short, and the body is long. If both if and else parts are long, I would extract them to separate functions.

这取决于树枝的长度。如果初始的if检查是短的,并且主体是长的,那么您描述的return/continue的使用是很好的。如果If和else部分都很长,我会将它们提取为独立的函数。

I recommend reading Code Complete, it discusses things like this a lot.

我推荐阅读完整的代码,它经常讨论这样的事情。

#4


11  

The code would be more readable if termination criteria are handled first. I always prefer, checking for conditions that require a break or return rather than those that would need lengthy code execution. I prefer:

如果首先处理终止条件,那么代码将更具可读性。我总是喜欢检查需要中断或返回的条件,而不是需要长时间代码执行的条件。我喜欢:

 if (termination condn) 
      return;
 // code 
 // code

to

if (success condn)
{
  // code
  // code
}
else
 return;

This makes reading and understanding the code easier.

这使得阅读和理解代码更加容易。

#5


6  

The glib answer is that it all depends.

巧妙的回答是,这要看情况而定。

My general feeling is that if condition is a rare, guard (e.g. check for null) or error condition then I tend to use return or continue

我的一般感觉是,如果条件是罕见的,保护(例如检查null)或错误条件,那么我倾向于使用return或continue

If it's an expected case then I tend to use your first approach.

如果这是预期的情况,我倾向于使用你的第一种方法。

Notice, however, that I said "tend". The boundary between these to conditions is vague and subject to change depending on the project and who I'm working with.

注意,我说的是“倾向”。它们与条件之间的界限是模糊的,可能会根据项目和我的合作伙伴而改变。

#6


4  

I usually prefer

我通常喜欢

while( loopCondition ) {
    if( innerCondition ) {
        DoStuff();
    } else {
        DoOtherStuff(); 
    }
}

continue can be hard to follow if the length of DoStuff passed the 1-2 line threshold (and its fairly easy to miss the intention). This seems like a good opportunity to refactor the logic into some smaller methods.

如果DoStuff的长度超过了1-2行阈值(而且很容易忽略意图),则很难跟踪continue。这似乎是一个很好的机会,可以将逻辑重构到一些更小的方法中。

#7


4  

Do not sacrifice readability for premature optimization.

不要为了过早的优化而牺牲可读性。

For example:

例如:

void function() {
    if( condition ) {
        //do some stuff
    } else {
        //do other stuff
    }
}

is in most cases binary equivalent to

在大多数情况下,二进制等于?

void function() {
    if( condition ) {
        //do some stuff
        return;
    }
    //do other stuff
}

(i.e. the resulting code is probably the same). But the readability of the former is much better, because you can clearly see that the code will to either X or Y.

(即产生的代码可能是相同的)。但是前者的可读性要好得多,因为您可以清楚地看到代码将指向X或Y。

#8


3  

1) Input or object state validation. Following code:

1)输入或对象状态验证。下面的代码:

void function() {
    if( condition ) {
        //do some stuff
        return;
    }
    //do other stuff
}

is good when the condition is some requirement for function to work. It's a stage of input validation or object state validation. It then feels right to use return immediately to emphasis, that function did not run at all.

当条件是对工作的一些要求时是好的。它是输入验证或对象状态验证的阶段。然后感觉应该立即使用return来强调,这个函数根本没有运行。

2) Multistage processing. While/continue is good when the loop pops elements from some collection and processes them in multistage manner:

2)多级处理。当循环从某些集合中取出元素并以多阶段方式处理时,/continue是好的:

while(foo = bar.getNext()) {
   if(foo.empty())
       continue;
   if(foo.alreadyProcessed())
       continue;
   // Can we take a shortcut?
   if(foo.tryProcessThingsYourself())
       continue;
   int baz = foo.getBaz();
   if(baz < 0) {
       int qux = foo.getQux();
       if(qux < 0) {
         // Error - go to next element
         continue;
       }
   }
   // Finally -- do the actual processing
   baz = baz * 2;
   foo.setBaz(baz);
}

The example shows how natural it is to use continue in scenario when series of multistage processing is done, when each processing can be interrupted by various conditions in various places.

该示例展示了在执行一系列多阶段处理时,当每个处理可以被不同地方的不同条件中断时,在场景中使用continue是多么自然。

Notice: plinth posted real-life example, which follows what 2) says.

注意:plinth贴出了现实生活中的例子,它遵循了2)所说的。

3) General rule. I use continue and return when it corresponds with fact that something has been interrupted. I use else, when the else is part of actual processing.

3)一般规则。我使用continue和return,当它与某事被中断相对应时。当else是实际处理的一部分时,我使用else。

#9


2  

One possible maintenance issue is that if a function has multiple returns, then it is harder to stick a breakpoint or tracing at the return when debugging. This is only rarely an issue, but when you do miss a return point it's a pain. I don't think it matters so much for continue in loops, since the loop condition and the top of the loop are both still unique.

一个可能的维护问题是,如果一个函数有多个返回,那么在调试时很难在返回中插入断点或跟踪。这很少是一个问题,但是当你错过一个返回点时,这是一种痛苦。我不认为它在循环中很重要,因为循环条件和循环的顶部都是唯一的。

Aside from that: what everyone else says. Do what's most readable, which depends on the relative length, importance, and likelihood of "some stuff" and "other stuff". The shorter, more trivial, and more unlikely a case is, the less disturbing it is for it to have special-case control flow.

除此之外:别人怎么说。做最易读的事情,这取决于“一些东西”和“其他东西”的相对长度、重要性和可能性。一个案例越短,越简单,越不可能发生,越不令人不安的是它有特殊情况控制流程。

#10


2  

as other people said, only use return/continue if things are short.

正如其他人所说,只有在事情很短的时候才使用return/continue。

Personally i only use continue if it is possible to write on one line like:

我个人只会继续使用,如果可以在一行上写:

while( loopCondition ) {
    if( innerCondition ) continue;

    //do other stuff
}

If it's not possible to write it like this without code getting ugly, then if / else.

如果不让代码变得难看就不能这样写,那么If / else。

#11


2  

For grins, I did a search across my company's codebase for "continue;" just to get an idea of where it's being used. We use if 695 times across 59 projects in one solution, roughly 1500 source files.

对于grins,我在我的公司的代码库中搜索了“continue”,只是想知道它在哪里被使用。我们在一个解决方案中使用了695次,在一个解决方案中使用了大约1500个源文件。

The main ways I see them being used are as a quick filter:

我看到他们被使用的主要方式是作为一个快速过滤器:

foreach (Frobozz bar in foo) {
    if (QuickFilterExclude(bar))
        continue;
    // extensive processing
}

A recovery from an expected exception:

从预期的异常中恢复:

foreach (Frobozz bar in foo) {
    Baz result = new Baz(kDefaultConfiguration);
    try {
        Baz remoteResult = boo.GetConfiguration();
    }
    catch (RemoteConnectionException) {
        continue;
    }
    result.Merge(remoteResult);
    ReportResult(result);
}

And finally in state machinery.

最后是国家机器。

#12


1  

I generally use the if-return method when jumping out of a method or loop because there is nothing to be done.

当跳出一个方法或循环时,我通常使用if-return方法,因为没有什么要做的。

If the body is longer because substantial work is being done, I suggest using if-else and maybe using #region to give blocks a sensible name and have them easily collapsable for people to study the control flow. That or make separate methods :)

如果主体较长,因为正在进行大量工作,我建议使用If -else,或者使用#region给块一个合理的名称,使它们易于折叠,以便人们研究控制流。或单独制作方法:)

#13


0  

I had the following in my code:

我的代码如下:

    while(){
      boolean intersect = doesIntersect(interval_1,interval_2);
      if(!intersect){
         array.add(interval_2);
         if(// another condition){
            // Do some thing here
         }
         continue;
      }
      // other stuff to do if intersect
    }

Was confusing whether I should use continue there or use else but I decided that the inner if condition might make the else not well readable, so I used continue.

我不知道我应该用continue还是用else,但是我觉得内部if条件可能会让else不太好读,所以我用continue。

I think readability is what matters!

我认为可读性才是最重要的!