if 和 if-else 之间有明显的区别吗?

发布于 2024-08-29 13:26:13 字数 809 浏览 4 评论 0原文

鉴于以下代码片段,有什么明显的区别吗?

public boolean foo(int input) {
   if(input > 10) {
       doStuff();
       return true;
   }
   if(input == 0) {
       doOtherStuff();
       return true;
   }

   return false;
}

public boolean foo(int input) {
   if(input > 10) {
      doStuff();
      return true;
   } else if(input == 0) {
      doOtherStuff();
      return true;
   } else {
      return false;
   }
}

或者单退出原则在这段代码中会更好...

public boolean foo(int input) {
   boolean toBeReturned = false;
   if(input > 10) {
      doStuff();
      toBeReturned = true;
   } else if(input == 0) {
      doOtherStuff();
      toBeReturned = true;
   }

   return toBeReturned;
}

是否有任何明显的性能差异?您认为其中一个比其他的更易于维护/可读吗?

Given the following code snippets, is there any appreciable difference?

public boolean foo(int input) {
   if(input > 10) {
       doStuff();
       return true;
   }
   if(input == 0) {
       doOtherStuff();
       return true;
   }

   return false;
}

vs.

public boolean foo(int input) {
   if(input > 10) {
      doStuff();
      return true;
   } else if(input == 0) {
      doOtherStuff();
      return true;
   } else {
      return false;
   }
}

Or would the single exit principle be better here with this piece of code...

public boolean foo(int input) {
   boolean toBeReturned = false;
   if(input > 10) {
      doStuff();
      toBeReturned = true;
   } else if(input == 0) {
      doOtherStuff();
      toBeReturned = true;
   }

   return toBeReturned;
}

Is there any perceptible performance difference? Do you feel one is more or less maintainable/readable than the others?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

[浮城] 2024-09-05 13:26:13

在第二个示例中,您非常清楚地表明这两个条件是互斥的。
对于第一个,情况不太清楚,并且在两个 if 之间添加对 input 的赋值(不太可能)的情况下,逻辑将会改变。
假设将来有人在第二个 if 之前添加 input = 0
当然这种情况不太可能发生,但是如果我们在这里谈论可维护性,if-else明确表示存在互斥的条件,而一堆if则不会,而且它们之间并不像if那样依赖-else 块。

编辑:现在我看到,在这个特定的示例中,return 子句强制相互排他性,但我们再次讨论的是可维护性和可读性。

不管怎样,关于性能,如果这是用Java编码的,你不应该关心几个if块的性能,如果它是在一个非常慢的硬件中嵌入C,也许,但肯定不是用java。

With the second example you state very clearly that both conditions are mutually exclusive.
With the first one, it is not so clear, and in the (unlikely) event that an assignment to input is added between both ifs, the logic would change.
Suppose someone in the future adds input = 0 before the second if.
Of course this is unlikely to happen, but if we are talking about maintainability here, if-else says clearly that there are mutually exclusive conditions, while a bunch of ifs don't, and they are not so dependent between each other as are if-else blocks.

edit:Now that I see, in this particular example, the return clause forces the mutual exclusivity, but again, we're talking about maintainability and readability.

Anyway, about performance, if this is coded in Java you shouldn't care for performance of a couple of if blocks, if it were embedded C in a really slow hardware, maybe, but certainly not with java.

静若繁花 2024-09-05 13:26:13

使用最能描述您意图的形式。

如果事情这么简单,就不要遵循单一退出原则——它只会让事情变得更加混乱。

Use whatever form best describes your intent.

Do not follow the single exit principle if things are this simple, though--it just makes it more confusing.

幸福%小乖 2024-09-05 13:26:13
  • 在第一个:

    最终有人会出于某种奇怪的原因,在你不注意的时候添加一些添加语句,这将使该方法在某些奇怪的条件下失败,每个人(或者最糟糕的是一个人)都会花费 4 小时。查看源代码并调试应用程序,终于发现中间有东西。

  • 第二个肯定更好,不仅可以防止这种情况,而且还有助于清楚地说明,不再是这个这个其他

    如果我们在 if 中编写的所有代码最多 10 行,这实际上并不重要,但不幸的是事实并非如此,存在其他程序员出于某种原因认为if 主体应该是 > 200 行长...无论如何。

  • 我不喜欢第三个,它迫使我寻找 return 变量,而且更容易找到 return 关键字

关于速度性能,它们(几乎)相同。不用担心这个。

  • In the first:

    somebody eventually, by some strange reason and when you're not looking will add some add statement that will make this method fail under certain strange conditions, everybody ( or worst, one single person ) will spend 4 hrs. watching the source code and debugging the application to finally found there was something in the middle.

  • The second is definitely better, not only it prevents this scenario, but also helps to clearly state , it this or this other no more.

    If all the code we write within an if where 10 lines long at most, this wouldn't matter really, but unfortunately that's not the case, there exists other programmers which by some reason think that a if body should be > 200 lines long... anyway.

  • I don't like the third, it forces me to look for the return variable, and it's easier to find the return keyword

About speed performance, they are ( almost ) identical. Don't worry about that.

几度春秋 2024-09-05 13:26:13

在你的最后一个例子中,不要这样做:

public boolean foo(int input) {
   boolean toBeReturned = false;
   if(input > 10) {
      doStuff();
      toBeReturned = true;
   } else if(input == 0) {
      doOtherStuff();
      toBeReturned = true;
   }

   return toBeReturned;
}

但是这个(注意Java的final的使用):

public boolean foo(int input) {
   final boolean toBeReturned;    // no init here
   if(input > 10) {
      doStuff();
      toBeReturned = true;
   } else if(input == 0) {
      doOtherStuff();
      toBeReturned = true;
   } else {
      toBeReturned = false;
   }
   return toBeReturned;
}

通过这样做,你可以明确你的意图,这对于支持“意图编程”的IDE来说是天赐之物(不需要“编译”来查看潜在的错误,即使在部分 AST 上,好的 IDE 也可以实时检查不完整的源代码并立即发出警告)。

这样您就可以确定不会忘记初始化返回值。如果您稍后决定毕竟需要另一个条件,那么这很好。

我一直这样做,自从我开始使用 IntelliJ IDEA(版本 4 左右,很久以前)以来更是如此,这让我避免了很多愚蠢的分散注意力的错误......

有些人会认为这代码太多了这样一个简单的例子,但完全没有抓住重点:重点是使意图清晰,以便代码易于阅读并且以后可以轻松扩展,而不会意外忘记分配toBeReturned,也不会意外忘记要从后面的子句中返回,您可以添加。

否则,如果“简洁”是游戏的名称,那么我会写:

public boolean foo(int a) {
  return a > 10 ? doStuff() : a == 0 ? doOtherStuff() : false; 
}

doStuffdoOtherStuff 都将返回 true。

In your last example, don't do this:

public boolean foo(int input) {
   boolean toBeReturned = false;
   if(input > 10) {
      doStuff();
      toBeReturned = true;
   } else if(input == 0) {
      doOtherStuff();
      toBeReturned = true;
   }

   return toBeReturned;
}

but this (notice the use of Java's final):

public boolean foo(int input) {
   final boolean toBeReturned;    // no init here
   if(input > 10) {
      doStuff();
      toBeReturned = true;
   } else if(input == 0) {
      doOtherStuff();
      toBeReturned = true;
   } else {
      toBeReturned = false;
   }
   return toBeReturned;
}

By doing so you make your intend clear and this is a godsend for IDEs supporting "programming by intention" (there's no need to "compile" to see potential errors, even on a partial AST, a good IDE can examine incomplete source in real-time and give you instant warnings).

This way you are sure not to forget to initialize your return value. This is great if later on you decide that after all you need another condition.

I do this all the time and even moreso since I started using IntelliJ IDEA (version 4 or so, a long time ago) and this has saved me so many silly distraction mistakes...

Some people will argue that this is too much code for such a simple case but that's entirely missing the point: the point is to make the intent clear so that the code reads easily and can be easily extended later on, without accidentally forgetting to assign toBeReturned and without accidentally forgetting to return from a later clause you may add.

Otherwise, if "conciseness" was the name of the game, then I'd write:

public boolean foo(int a) {
  return a > 10 ? doStuff() : a == 0 ? doOtherStuff() : false; 
}

Where both doStuff and doOtherStuff would return true.

痴情换悲伤 2024-09-05 13:26:13

从语义上来说——不。从性能角度来看,这取决于编译器,即它是否可以发现两个条件不能同时为真。我敢打赌标准 Sun 编译器可以。是否采用单出口原则取决于喜好。我个人讨厌它。

Semantically — no. Performance-wise this depends on compiler, i.e. whether it can spot that both conditions cannot be true at once. I'd bet standard Sun compiler can. Whether to use single exit principle depends on tastes. I personally hate it.

百思不得你姐 2024-09-05 13:26:13

版本 #1 和 #2 可能比 #3 更快,但我认为性能差异很小。我宁愿关注可读性

就我个人而言,我永远不会使用版本 #2。在 #1 和 #3 之间,我会选择为相关案例生成最具可读性的代码。我不喜欢我的方法中有很多退出点,因为它使代码难以分析。然而,在某些情况下,当我们针对某些特殊情况立即退出并继续主要情况时,流程会变得更加清晰。

Version #1 and #2 may be faster than #3, but I suppose the performance difference is minimal. I would rather focus on readability.

Personally, I would never use version #2. Between #1 and #3, I would choose the one that yields the most readable code for the case in question. I don't like many exit points in my methods, because it makes the code hard to analyze. However, there are cases where the flow becomes clearer when we exit immediately for some special cases, and continue with the main cases.

痴骨ら 2024-09-05 13:26:13

当两个示例不相似时,请考虑这种情况:

    public boolean foo(int input) {
        if (input > 10) {
            // doStuff();
            return true;
        }
        System.out.println("do some other intermediary stuff");
        if (input == 0) {
            // doOtherStuff();
            return true;
        }

        return false;
    }

    public boolean foo(int input) {
        if (input > 10) {
            // doStuff();
            return true;
        } 
        //System.out.println("doing some intermediary stuff... doesn't work");
        else if (input == 0) {
            // doOtherStuff();
            return true;
        } else {
            return false;
        }
        return false;
    }

第一种方法可能更灵活,但是两个公式在不同的情况下都有其用途。

关于性能,我认为对于任何由理智的程序员编写的常规 Java 应用程序来说,差异很小,值得考虑:)。

Think of this case when the two examples won't be similar:

    public boolean foo(int input) {
        if (input > 10) {
            // doStuff();
            return true;
        }
        System.out.println("do some other intermediary stuff");
        if (input == 0) {
            // doOtherStuff();
            return true;
        }

        return false;
    }

vs.

    public boolean foo(int input) {
        if (input > 10) {
            // doStuff();
            return true;
        } 
        //System.out.println("doing some intermediary stuff... doesn't work");
        else if (input == 0) {
            // doOtherStuff();
            return true;
        } else {
            return false;
        }
        return false;
    }

The first approach is probably more flexible, but both formulas have their use in different circumstances.

Regarding performance, I think the differences are to small to be taken in consideration, for any regular java application, coded by sane programmers :).

寒尘 2024-09-05 13:26:13

在您的情况下,第二个 if 仅在第一个 if 失败时才会被调用,因此这里不太重要,但如果您的第一个 if 做了某事并且没有返回,则第二个 if (然后总是 false)仍将被测试,除非它处于 else-if 中。

换句话说,在某些情况下,if-else-if 和 if-if 之间的差异很重要,但这不是其中之一。

示例:尝试这个,然后在删除 else 后尝试它。你会得到两个不同的输出:

int someNumber = 1;
if(someNumber < 5)
{
    someNumber += 5;
    Console.WriteLine("First call.");
}
else if(someNumber >= 5)
{
    Console.WriteLine("Second call.");
}

In your case the second if would only get called if the first if failed so it's less important here but if your first if did something and didn't return, the second if (which would then always be false) would still be tested unless it was in an else-if.

In other words, there are cases where the difference between if-else-if and if-if matters, but this isn't one of them.

Example: Try this and then try it after removing the else. You get two different outputs:

int someNumber = 1;
if(someNumber < 5)
{
    someNumber += 5;
    Console.WriteLine("First call.");
}
else if(someNumber >= 5)
{
    Console.WriteLine("Second call.");
}
誰認得朕 2024-09-05 13:26:13

第一个和第二个片段之间确实没有区别。然而第三个片段效率很低。因为您要等到方法中的最后一行代码才将程序的控制权返回给调用者,所以浪费了处理能力/内存,而前两个代码片段一旦确定其中一个条件为真,就会立即返回控制权。

Between the first and second snippets, there's really no difference. However the third snippet is quite inefficient. Because you wait to return control of the program to the caller until the last line of code in the method, you waste processing power/memory whereas the first two code snippets return control as soon as it determines one of the conditions to be true.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文