何时使用If-else if-else over switch语句,反之亦然

为什么你想在一系列的if语句中使用switch块呢?

switch语句似乎做同样的事情,但需要更长的时间来键入。

和大多数情况一样,你应该根据上下文select使用哪一个,以及在概念上什么是正确的方法。 一个开关实际上是说“根据这个variables值select其中之一”,但是if语句只是一系列的布尔检查。

举个例子,如果你在做:

 int value = // some value if (value == 1) { doThis(); } else if (value == 2) { doThat(); } else { doTheOther(); } 

这将会更好地performance为一个开关,因为它很明显地立即显示出动作的select是基于“值”的值而发生的,而不是一些任意的testing。

另外,如果您发现自己正在编写开关和if-elses,并使用面向对象的语言,则应考虑将其删除,并尽可能使用多态性来实现相同的结果。

最后,关于开关花费更长的时间,我不记得是谁说的,但是我曾经看过一个人问:“你的打字速度真的是影响你多快的代码吗? (转述)

如果你打开一个variables的值,那么我会每次都使用一个开关,这就是构造的目的。

否则,坚持使用多个if-else语句。

关于可读性:

我通常更喜欢if / else构造switch语句,特别是在允许翻转的情况下。 我经常发现的是,随着项目的老化,以及多个开发人员的参与,开始构buildswitch语句会遇到麻烦。

如果他们(陈述)变得更简单,许多程序员变得懒惰,而不是阅读整个陈述来理解它,他们只是在案件中popup来,以掩盖他们添加到陈述中的任何案件。

我已经看到许多代码在switch语句中重复的情况,因为一个人的testing已经被覆盖了,但是一个简单的例子就足够了,但是懒惰迫使他们在最后添加冗余代码,而不是试图理解开关。 我也看到一些噩梦般的转换陈述,其中许多案例构build不善,只是试图遵循所有的逻辑,许多分散在各处的突破案例,以及许多不是这样的案例变得困难……哪一种导致我谈到的第一个/冗余问题。

从理论上讲,if / else构造可能存在同样的问题,但实际上这似乎并不经常发生。 也许(只是猜测)程序员被迫仔细阅读一些,因为你需要了解在if / else结构中被testing的更复杂的情况, 如果你写的东西很简单,你知道其他人可能永远不会触及,而且你可以很好地构build它,那么我猜这是一种折腾。 在这种情况下,任何可读性和可读性都可能是正确的答案,因为你可能会维护这些代码。

关于速度:

switch语句通常比if-else结构(但并非总是)执行得更快。 由于switch语句的可能值是事先规定好的,因此编译器可以通过构build跳转表来优化性能。 每个条件都不需要像if / else构造那样进行testing(好吧,直到find合适的东西)。

不过,情况并非总是如此。 如果你有一个简单的开关,比如可能的值为1到10,情况就是这样。 你添加的值越多, 跳转表就越大,交换机的效率就越低(不比if / else要低,但比相对简单的switch语句效率低) 。 而且,如果这些值是高度变化的(即,而不是1到10,则有10个可能的值,例如,1000,10000,100000,等等到100000000000),则该开关比在更简单的情况下效率低。

希望这可以帮助。

我个人更喜欢看太多嵌套的if-elses的switch语句,因为它们可以更容易阅读。 显示状态的开关在可读性方面也更好。

请参阅这篇文章中关于pacman ifs的评论。

这很大程度上取决于具体情况。 最好,我认为如果有很多嵌套的if-else ,我们应该使用if-elseswitch

问题是多less?

昨天我问自己同样的问题:

 public enum ProgramType { NEW, OLD } if (progType == OLD) { // ... } else if (progType == NEW) { // ... } if (progType == OLD) { // ... } else { // ... } switch (progType) { case OLD: // ... break; case NEW: // ... break; default: break; } 

在这种情况下,第一个if有不必要的第二个testing。 第二次感觉有点不好,因为它隐藏了新的。

我最终select了switch因为它读得更好。

开关语句更易于阅读和维护,而不用担心。 而且通常更快,更不容易出错。

每次在单个variables上有两个以上的条件时使用开关,例如平日,如果每个工作日有不同的动作,则应使用开关。

其他情况(多个variables或复杂的条款,你应该如果,但没有一个规则在哪里使用每个。

我经常认为,如果没有异味,使用elseif并通过案例实例(在语言允许的情况下)是代码异味。

对于我自己,我通常发现嵌套(if / then / else)通常比elseif更好地反映事物,对于相互排斥的情况(通常是一个属性组合比另一个更优先),case或类似的东西更清晰两年后再读。

我认为Rexx使用的select语句是一个特别好的例子,说明如何做好“Case”(没有下拉)(愚蠢的例子):

 Select When (Vehicle ¬= "Car") Then Name = "Red Bus" When (Colour == "Red") Then Name = "Ferrari" Otherwise Name = "Plain old other car" End 

哦,如果优化不能达到它,得到一个新的编译器或语言…

由于需要更长的时间才能避免出现这种情况,这是一件坏事,试图将其解决。 也就是说,过于冗长的东西也难以阅读,所以小而简单是重要的,但它的可读性不重要。 简洁的单线通常比简单的三线或四线难以阅读。

使用最好的结构来描述操作的逻辑。

假设您已经决定使用开关,因为您只处理可能具有不同值的单个variables。 如果这会导致一个小的switch语句(2-3例),我会说这很好。 如果看起来你会最终得到更多,我会推荐使用多态。 这里可以使用AbstractFactory模式来创build一个对象,该对象将执行您在交换机中执行的任何操作。 丑陋的switch语句将被抽象出来,并且最终得到更简洁的代码。