何时使用if else if else 和 switch语句,反之亦然

When to use If-else if-else over switch statements and vice versa

本问题已经有最佳答案,请猛点这里访问。

为什么要在一系列if语句上使用switch块?

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


与大多数事情一样,您应该根据上下文和概念上正确的方式来选择要使用的内容。开关实际上是说"根据这个变量值选择其中一个",但是if语句只是一系列布尔检查。

例如,如果您正在执行以下操作:

1
2
3
4
5
6
7
8
int value = // some value
if (value == 1) {
    doThis();
} else if (value == 2) {
    doThat();
} else {
    doTheOther();
}

这可以更好地表示为一个开关,因为它会立即使操作的选择发生在"值"的值上,而不是一些任意的测试。

另外,如果你发现自己在写开关,如果是ELSE,使用OO语言,你应该考虑去掉它们,如果可能的话,使用多态性来实现相同的结果。

最后,关于切换需要更长的时间来输入,我不记得是谁说的,但我读过一次有人问:"你的输入速度真的是影响你编码速度的因素吗?"(释义)


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

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


关于可读性:

我通常更喜欢if/else构造而不是switch语句,特别是在允许通过案例的语言中。我经常发现,随着项目的老化和多个开发人员的参与,您将开始在switch语句的构造上遇到困难。

如果它们(语句)变得更简单,那么许多程序员就会变得懒惰,而不是阅读整个语句来理解它,它们只会出现在一个案例中,以涵盖它们添加到语句中的任何案例。

我见过很多这样的情况:代码在switch语句中重复,因为一个人的测试已经被覆盖了,虽然这种情况很简单,但是懒惰迫使他们在末尾添加多余的代码,而不是试图理解开关。我也看到过一些恶梦般的switch语句,其中有许多情况构造得不好,只是试图遵循所有的逻辑,其中许多情况分散在各处,而许多情况并非如此,这就变得困难了……哪种方式导致了第一个/冗余问题。

理论上,if/else构造也可能存在同样的问题,但实际上,这种情况似乎并不经常发生。也许(只是猜测)程序员被迫更仔细地阅读,因为您需要了解if/else构造中测试的更复杂的条件?如果你写的东西很简单,你知道别人可能永远不会碰,而且你能很好地构造它,那么我猜这是一个折腾。在这种情况下,任何对您来说更具可读性和感觉最好的东西都可能是正确的答案,因为您很可能正在维护该代码。

关于速度:

switch语句通常比if-else构造执行得更快(但并非总是如此)。由于switch语句的可能值是预先安排好的,因此编译器能够通过构造跳转表来优化性能。每个条件都不必像在if/else构造中那样进行测试(好吧,直到找到正确的条件为止)。

然而,情况并非总是如此。如果你有一个简单的开关,比如说,可能的值是1到10,情况就是这样。添加的值越多,跳转表就越大,切换的效率就越低(不比if/else高,但比比较简单的switch语句低)。此外,如果值是高度变化的(即,不是1到10,而是1、1000、10000、100000等10个可能的值到1000000000),则开关的效率低于简单情况下的效率。

希望这有帮助。


我个人更喜欢看到切换语句,而不是太多嵌套的if-else,因为它们更容易阅读。开关在可读性方面也更适合显示状态。

另请参阅本文中关于PacmanIFS的评论。


switch语句更容易阅读和维护,而且非常简单。通常速度更快,出错率更低。


我经常认为,使用Elseif和Droppingthrough实例(语言允许的情况下)是代码气味,如果不是气味的话。

对于我自己,我通常发现嵌套的(if/then/else)通常比else if s更好地反映事物,而对于互斥的情况(通常一种属性组合优先于另一种属性组合),两年后可以更清楚地阅读case或类似的东西。

我认为rexx使用的select语句是如何做好"case"的一个特别好的例子(没有遗漏)(愚蠢的例子):

1
2
3
4
5
6
7
8
Select
    When (Vehicle ?="Car") Then
        Name ="Red Bus"
    When (Colour =="Red") Then
        Name ="Ferrari"
    Otherwise
        Name ="Plain old other car"
    End

哦,如果优化还不够,那就换一个新的编译器或者语言吧…


假设您已经决定使用switch,因为您只处理具有不同值的单个变量。如果这会导致一个小的switch语句(2-3个案例),我会说这很好。如果你最终会得到更多,我建议你用多态性来代替。AbstractFactory模式可以在这里用于创建一个对象,该对象将执行您试图在交换机中执行的任何操作。丑陋的switch语句将被抽象掉,最终得到更干净的代码。


这在很大程度上取决于具体情况。如果有许多嵌套的if-elses,我认为最好使用switch而不是if-else

问题是多少是多少?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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进行了不必要的第二次测试。第二种感觉有点不好,因为它隐藏了新的。

我最终选择了switch,因为它读起来更好。


每次在一个变量上有两个以上的条件时,请使用switch,例如,如果每个工作日的操作不同,则应使用switch。

其他情况(多个变量或复杂的if子句,您应该假设,但没有关于在哪里使用它们的规则)。


因为打字时间长而避免输入东西的倾向是一件坏事,试着根除它。也就是说,过于冗长的内容也很难阅读,所以小而简单很重要,但可读性而不是可写性才是重要的。简明扼要的一句话往往比简单的、布局良好的3或4行更难阅读。

使用最能描述操作逻辑的构造。