简体   繁体   English

什么放在IF块中以及放入ELSE块中的内容?

[英]What to put in the IF block and what to put in the ELSE block?

This is a minor style question, but every bit of readability you add to your code counts. 这是一个次要的样式问题,但是您添加到代码中的每一点可读性都很重要。

So if you've got: 所以,如果你有:

if (condition) then
{
   // do stuff
}
else
{
   // do other stuff
}

How do you decide if it's better like that, or like this: 你如何决定它是否更好,或者像这样:

   if (!condition) then
   {
     // do other stuff
   {
   else
   {
     // do stuff
   }

My heuristics are: 我的启发式是:

  1. Keep the condition positive (less mental calculation when reading it) 保持病情积极(阅读时心理计算较少)
  2. Put the most common path into the first block 将最常见的路径放入第一个块

I prefer to put the most common path first, and I am a strong believer in nesting reduction so I will break, continue, or return instead of elsing whenever possible. 我更喜欢把最常见的路径放在第一位,而且我坚信减少嵌套,所以我会尽可能地打破,继续或返回,而不是精益求精。 I generally prefer to test against positive conditions, or invert [and name] negative conditions as a positive. 我通常更倾向于测试正面条件,或者将[和名称]负面条件反转为正面。

if (condition)
    return;

DoSomething();

I have found that by drastically reducing the usage of else my code is more readable and maintainable and when I do have to use else its almost always an excellent candidate for a more structured switch statement. 我发现通过大幅减少else的使用,我的代码更具可读性和可维护性,当我必须使用else时,它几乎总是一个更好的候选者,用于更结构化的switch语句。

Two (contradictory) textbook quotes: 两个(矛盾的)教科书引用:

Put the shortest clause of an if/else on top 将if / else的最短子句置于顶部

--Allen Holub, "Enough Rope to Shoot Yourself in the Foot", p52 --Allen Holub,“足够的绳索射击自己的脚”,第52页

Put the normal case after the if rather than after the else 将正常情况放在if之后而不是在else之后

--Steve McConnell, "Code Complete, 2nd ed.", p356 --Steve McConnell,“Code Complete,2nd ed。”,第356页

I prefer the first one. 我更喜欢第一个。 The condition should be as simple as possible and it should be fairly obvious which is simpler out of condition and !condition 条件应该尽可能简单,它应该是相当明显的,更简单的条件和条件

It depends on your flow. 这取决于你的流量。 For many functions, I'll use preconditions: 对于许多函数,我将使用前提条件:

bool MyFunc(variable) {
    if (variable != something_i_want)
        return false;

    // a large block of code
    // ...
    return true;
}

If I need to do something each case, I'll use an if (positive_clause) {} else {} format. 如果我需要一些事情每一种情况下,我将使用一个if (positive_clause) {} else {}格式。

If the code is to check for an error condition, I prefer to put that code first, and the "successful" code second; 如果代码是检查错误条件,我更喜欢先放置代码,然后将“成功”代码放在第二位; conceptually, this keeps a function call and its error-checking code together, which makes sense to me because they are related. 从概念上讲,这将函数调用及其错误检查代码保持在一起,这对我来说是有意义的,因为它们是相关的。 For example: 例如:

  if (!some_function_that_could_fail())
  {
     // Error handling code
  }
  else
  {
     // Success code
  }

I agree with Oli on using a positive if clause when possible. 我同意Oli在可能的情况下使用积极的if条款。

Just please never do this: 请永远不要这样做:

if (somePositiveCondition)
else {
    //stuff
}

I used to see this a lot at one place I worked and used to wonder if one of the coders didn't understand how not works... 我曾经在我工作的一个地方经常看到这个,并常常想知道其中一个程序员是否不理解如何不工作......

When I am looking at data validation, I try to make my conditions "white listing" - that is, I test for what I will accept: 当我在查看数据验证时,我会尝试将我的条件设为“白名单” - 也就是说,我会测试我接受的内容:

if DataIsGood() then
   DoMyNormalStuff
else
   TakeEvasiveAction

Rather than the other way around, which tends to degenerate into: 而不是相反,往往退化为:

if SomeErrorTest then
  TakeSomeEvasiveAction
else if SomeOtherErrorCondition then
  CorrectMoreStupidUserProblems
else if YetAnotherErrorThatNoOneThoughtOf then
  DoMoreErrorHandling
else
  DoMyNormalStuff

I know this isn't exactly what you're looking for, but ... A lot of developers use a "guard clause", that is, a negative "if" statement that breaks out of the method as soon as possible. 我知道这不是你正在寻找的,但是......很多开发人员使用“保护条款”,即一个消极的“if”语句,尽快打破方法。 At that point, there is no "else" really. 那时,真的没有“别的”。

Example: 例:

if (blah == false)
{
    return; // perhaps with a message
}

// do rest of code here...

There are some hard-core c/c++/assembly guys out there that will tell you that you're destroying your CPU!!! 有一些硬核c / c ++ /汇编人员会告诉你,你正在摧毁你的CPU! (in many cases, processors favor the "true" statement and try to "prefetch" the next thing to do... so theoretically any "false" condition will flush the pipe and will go microseconds slower). (在许多情况下,处理器偏爱“真实”语句并试图“预取”下一件事......所以理论上任何“假”条件都会刷新管道并且会慢几微秒)。

In my opinion, we are at the point where "better" (more understandable) code wins out over microseconds of CPU time. 在我看来,我们正处于“更好”(更易理解)的代码胜过超过几秒的CPU时间。

I think that for a single variable the not operator is simple enough and naming issues start being more relevant. 我认为对于单个变量,not运算符非常简单,命名问题开始变得更加相关。

Never name a variable not_X, if in need use a thesaurus and find an opposite. 永远不要将变量not_X命名,如果需要使用同义词并找到相反的变量。 I've seen plenty of awful code like 我见过很多糟糕的代码

if (not_dead) {
} else {
}

instead of the obvious 而不是显而易见的

if (alive) {
} else {
}

Then you can sanely use (very readable, no need to invert the code blocks) 然后你可以理智地使用(非常易读,无需反转代码块)

if (!alive) {
} else {
}

If we're talking about more variables I think the best rule is to simplify the condition. 如果我们谈论更多变量,我认为最好的规则是简化条件。 After a while projects tend to get conditions like: 过了一段时间项目往往会得到如下条件:

if (dead || (!dead && sleeping)) {
} else {
}

Which translates to 这转化为

if (dead || sleeping) {
} else {
}

Always pay attention to what conditions look like and how to simplify them. 始终注意什么样的条件以及如何简化它们。

Software is knowledge capture. 软件是知识捕获。 You're encoding someone's knowledge of how to do something. 你正在编码某人对如何做某事的知识。

The software should fit what's "natural" for the problem. 该软件应该适合问题的“自然”。 When in doubt, ask someone else and see what people actually say and do. 如有疑问,请询问其他人并查看人们的实际说法和行为。

What about the situation where the "common" case is do nothing? 那些“普通”案件无所作为的情况怎么样? What then 然后怎样呢

if( common ) {
    // pass
}
else {
    // great big block of exception-handling folderol
}

Or do you do this? 或者你这样做?

if( ! common ) {
    // great big block of except-handling folderol
}

The "always positive" rule isn't really what you want first. “永远积极”的规则并不是你想要的。 You want to look at rules more like the following. 您想要查看更像以下规则。

  1. Always natural -- it should read like English (or whatever the common language in your organization is.) 永远自然 - 它应该像英语(或任何组织中的通用语言)。
  2. Where possible, common cases first -- so they appear common. 在可能的情况下,首先是常见案例
  3. Where possible use positive logic; 尽可能使用正逻辑; negative logic can be used where it's commonly said that way or where the common case is a do-nothing. 负逻辑可用于通常以这种方式表达的地方,或者常见情况是什么都不做的地方。

If one of the two paths is very short (1 to 10 lines or so) and the other is much longer, I follow the Holub rule mentioned here and put the shorter piece of code in the if. 如果两条路径中的一条非常短(1到10行左右)而另一条路径更长,我遵循这里提到Holub规则并将更短的代码放在if中。 That makes it easier to see the if/else flow on one screen when reviewing the code. 这使得在查看代码时更容易在一个屏幕上看到if / else流。

If that is not possible, then I structure to make the condition as simple as possible. 如果那是不可能的,那么我构造使条件尽可能简单。

For me it depends on the condition, for example: 对我来说,这取决于条件,例如:

if (!PreserveData.Checked)
{  resetfields();}

I tend to talk to my self with what I want the logic to be and code it to the little voice in my head. 我倾向于用我想要的逻辑与自己交谈,并将其编码为我脑子里的小声音。

You can usually make the condition positive without switching around the if / else blocks. 您通常可以在不切换if / else块的情况下使条件为正。

Change 更改

   if (!widget.enabled()) {
     // more common 
   } else {
     // less common 
   }

to

   if (widget.disabled()) {
     // more common 
   } else {
     // less common
   }

Intel Pentium branch prediction pre-fetches instructions for the "if" case. 英特尔奔腾分支预测预取“if”情况的指令。 If it instead follows the "else" branch: it has the flush the instruction pipeline, causing a stall. 如果它跟在“else”分支之后:它具有刷新指令管道,导致停顿。

If you care a lot about performance: put the most likely outcome in the 'if' clause. 如果你非常关心表现:把最可能的结果放在'if'条款中。

Personally i write it as 我个人把它写成

if (expected)
{
   //expected path
}
else
{
   //fallback other odd case
} 

If you have both true and false conditions then I'd opt for a positive conditional - This reduces confusion and in general I believe makes your code easier to read. 如果您同时拥有真假条件,那么我会选择积极的条件 - 这可以减少混淆,一般来说,我相信会让您的代码更容易阅读。

On the other hand, if you're using a language such as Perl, and particularly if your false condition is either an error condition or the most common condition, you can use the 'unless' structure, which executes the code block unless the condition is true (ie the opposite of if): 另一方面,如果您使用的是Perl之类的语言,特别是如果您的错误条件是错误条件或最常见的条件,您可以使用'unless'结构,它执行代码块,除非条件是真的(即if的反面):

unless ($foo) {
    $bar;
}

First of all, let's put aside situations when it is better to avoid using "else" in the first place (I hope everyone agrees that such situations do exist and determining such cases probably should be a separate topic). 首先,让我们暂时搁置最好避免首先使用“其他”的情况(我希望每个人都同意这种情况确实存在并且确定这种情况可能应该是一个单独的主题)。

So, let's assume that there must be an "else" clause. 所以,我们假设必须有一个“else”子句。

I think that readability/comprehensibility imposes at least three key requirements or rules, which unfortunately often compete with each other: 我认为可读性/可理解性至少强加了三个关键要求或规则,不幸的是它们经常相互竞争:

  1. The shorter is the first block (the "if" block) the easier is it to grasp the entire "if-else" construct. 第一个块(“if”块)越短,就越容易掌握整个“if-else”结构。 When the "if" block is long enough, it becomes way too easy to overlook existence of "else" block. 当“if”块足够长时,很容易忽略“else”块的存在。

  2. When the "if" and "else" paths are logically asymmetric (eg "normal processing" vs. "error processing"), in a standalone "if-else" construct it does not really matter much which path is first and which is second. 当“if”和“else”路径在逻辑上不对称时(例如“正常处理”与“错误处理”),在独立的 “if-else”构造中,哪个路径首先是哪个路径并且哪个路径是第二个并不重要。 However, when there are multiple "if-else" constructs in proximity to each other (including nesting), and when all those "if-else" constructs have asymmetry of the same kind - that's when it is very important to arrange those asymmetric paths consistently. 但是,当有多个 “if-else”构造彼此接近时(包括嵌套),并且当所有那些“if-else”构造具有相同类型的不对称时 - 那就是排列那些非对称路径非常重要的时候一致。

    Again, it can be "if ... normal path ... else ... abnormal path" for all, or "if ... abnormal path ... else ... normal path" for all, but it should not be a mix of these two variants. 同样,对于所有人来说,它可以是“如果...正常路径......其他......异常路径”,或者“如果...异常路径......其他......正常路径”,但它不应该是这两种变体的混合体。

    With all other conditions equal, putting the normal path first is probably more natural for most human beings (I think it's more about psychology than aesthetics :-). 在所有其他条件相同的情况下,将正常路径放在第一位对于大多数人来说可能更自然(我认为它更多地是关于心理学而不是美学:-)。

  3. An expression that starts with a negation usually is less readable/comprehensible than an expression that doesn't. 以否定开头的表达式通常比不具有否定性的表达式更不易读/可理解。

So, we have these three competing requirements/rules, and the real question is: which of them are more important than others. 因此,我们有这三个相互竞争的要求/规则,真正的问题是:哪一个比其他更重要。 For Allen Holub the rule #1 is probably the most important one. 对于Allen Holub来说,规则#1可能是最重要的规则。 For Steve McConnell - it is the rule #2. 史蒂夫麦康奈尔 - 这是规则#2。 But I don't think that you can really choose only one of these rules as a single quideline. 但我认为你不能真正选择其中一条作为单一的准则。

I bet you've already guessed my personal priorities here (from the way I ordered the rules above :-). 我打赌你已经在这里猜到了我的个人优先事项(从我订购上述规则的方式:-)。

My reasons are simple: 我的理由很简单:

  • The rule #1 is unconditional and impossible to circumvent. 规则#1是无条件的,不可能规避。 If one of the blocks is so long that it runs off the screen - it must become the "else" block. 如果其中一个块太长而无法在屏幕上运行 - 它必须成为“其他”块。 (No, it is not a good idea to create a function/method mechanically just to decrease the number of lines in an "if" or "else" block! I am assuming that each block already has a logically justifiable minimum amount of lines.) (不,机械地创建函数/方法只是为了减少“if”或“else”块中的行数并不是一个好主意!我假设每个块已经具有逻辑上合理的最小行数。 )

  • The rule #2 involves a lot of conditions: multiple "if-else" constructs, all having asymmetry of the same kind, etc. So it just does not apply in many cases. 规则#2涉及很多条件:多个“if-else”构造,都具有相同类型的不对称性等等。因此它在许多情况下不适用。

    Also, I often observe the following interesting phenomenon: when the rule #2 does apply and when it is used properly, it actually does not conflict with the rule #1! 此外,我经常观察到以下有趣的现象:当规则#2适用时以及正确使用时,它实际上与规则#1不冲突! For example, whenever I have a bunch of "if-else" statements with "normal vs. abnormal" asymmetry, all the "abnormal" paths are shorter than "normal" ones (or vice versa). 例如,每当我有一堆“if-else”语句具有“正常与异常”不对称时,所有“异常”路径都比“正常”路径短(反之亦然)。 I cannot explain this phenomenon, but I think that it's just a sign of good code organization. 我无法解释这种现象,但我认为这只是良好代码组织的标志。 In other words, whenever I see a situation when rules #1 and #2 are in conflict, I start looking for "code smells" and more often than not I do find some; 换句话说,每当我看到规则#1和#2发生冲突的情况时,我就开始寻找“代码味道”,而且我经常会找到一些; and after refactoring - tada! 重构后 - tada! no more painful choosing between rule #1 and rule #2, :-) 规则#1和规则#2之间没有更痛苦的选择,:-)

  • Finally, the rule #3 hase the smallest scope and therefore is the least critical. 最后,规则#3具有最小的范围,因此是最不重要的。

    Also, as mentined here by other colleagues, it is often very easy to "cheat" with this rule (for example, to write "if(disabled),,," instead of "if(!enabled)..."). 此外,正如其他同事在这里所说的那样,通常很容易“欺骗”这个规则(例如,写“if(disabled),,,”而不是“if(!enabled)...”)。

I hope someone can make some sense of this opus... 我希望有人能对这一作品有所了解......

I generally put the positive result (so the method) at the start so: 我通常在开始时把积极的结果(所以方法)放在一起,所以:

if(condition)
{
doSomething();
}
else
{
System.out.println("condition not true")
}

But if the condition has to be false for the method to be used, I would do this: 但是如果要使用的方法的条件必须为false,我会这样做:

if(!condition)
{
doSomething();
}
else
{
System.out.println("condition true");
}

作为一般规则,如果一个明显大于另一个,我将较大的一个作为if块。

  1. put the common path first 把共同的道路放在首位
  2. turn negative cheking into positive ones ( !full == empty ) 把负面的cheking变成正面的( !full == empty

If you must have multiple exit points, put them first and make them clear: 如果您必须有多个退出点,请先将它们放在一起并清除它们:

if TerminatingCondition1 then
  Exit
if TerminatingCondition2 then
  Exit

Now we can progress with the usual stuff: 现在我们可以用通常的东西进步:

if NormalThing then
  DoNormalThing
else
  DoAbnormalThing

I always keep the most likely first. 我总是最有可能保持第一。

In Perl I have an extra control structure to help with that. 在Perl中,我有一个额外的控制结构来帮助解决这个问题。 The inverse of if. if的反转。

unless (alive) {
     go_to_heaven;
} else {
     say "MEDIC";
}

You should always put the most likely case first. 你应该始终把最可能的案例放在第一位。 Besides being more readable, it is faster. 除了更具可读性之外,它更快。 This also applies to switch statements. 这也适用于switch语句。

I'm horrible when it comes to how I set up if statements. 关于我如何设置if语句,我很可怕。 Basically, I set it up based on what exactly I'm looking for, which leads everything to be different. 基本上,我根据我正在寻找的东西来设置它,这导致一切都不同。

if (userinput = null){ if(userinput = null){
explodeViolently(); explodeViolently();
} else { } else {
actually do stuff; 实际做的东西;
} }

or perhaps something like 或者类似的东西

if (1+1=2) { if(1 + 1 = 2){
do stuff; 做东西;
} else { } else {
explodeViolently(); explodeViolently();
} }

Which section of the if/else statement actually does things for me is a bad habit of mine. if / else语句的哪一部分实际上对我有用,这是我的一个坏习惯。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Ruby中这些块编码样式的区别或价值是什么? - What is the difference or value of these block coding styles in Ruby? 在try块中,应该仅是可能引发异常或可以放置一些与异常无关的代码的指令? - Inside a try block should only be the instructions that could throw the exception or can put some code not relevant for the exception? 定义函数时,应按什么顺序放置参数? - When I define functions, in what order should I put the parameters? 您将方法按什么顺序放在类代码中? - In what order do you put methods in class code? 好的Haskell编码风格的if / else控制块? - Good Haskell coding style of if/else control block? 如何使用 if..else 块的结果分配变量? - How do you assign a variable with the result of a if..else block? 我尝试了这个简单的javascript代码 if else block Error:-Declaration or statement expected - I tried this javascript code of simple if else block Error:-Declaration or statement expected 重构这些嵌套的for / else循环的最pythonic方法是什么(如果有的话)? - What's the most pythonic way (if any) to refactor these nested for/else loops? Python尝试块大小 - Python try block size JavaScript应该放在哪里? - Where should JavaScript be put?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM