为什么要switch
在一系列if
语句上使用块?
switch
语句似乎做同样的事情,但需要更长的时间来输入。
与大多数事情一样,您应该根据上下文以及概念上正确的方式来选择使用哪个。开关实际上是在说“根据此变量值选择其中一个”,但 if 语句只是一系列布尔检查。
例如,如果您正在执行以下操作:
int value = // some value
if (value == 1) {
doThis();
} else if (value == 2) {
doThat();
} else {
doTheOther();
}
这将更好地表示为一个开关,因为它可以立即清楚地表明,行动的选择是基于“价值”的价值而不是一些任意的测试。
此外,如果您发现自己编写开关和 if-else 并使用 OO 语言,您应该考虑摆脱它们并尽可能使用多态性来实现相同的结果。
最后,关于切换输入需要更长的时间,我不记得是谁说的,但我曾经读过有人问“你的打字速度真的会影响你编码的速度吗?” (转述)
如果您要打开单个变量的值,那么我每次都会使用一个开关,这就是构造的目的。
否则,坚持使用多个 if-else 语句。
我通常更喜欢 if/else 构造而不是 switch 语句,尤其是在允许失败案例的语言中。我经常发现,随着项目的老化和多个开发人员的参与,您将开始在构建 switch 语句时遇到麻烦。
如果它们(语句)变得不那么简单,许多程序员就会变得懒惰,而不是阅读整个语句来理解它,他们会简单地弹出一个 case 来覆盖他们添加到语句中的任何 case。
我见过很多代码在 switch 语句中重复的情况,因为一个人的测试已经被覆盖,一个简单的 fall-though 情况就足够了,但是懒惰迫使他们在最后添加冗余代码,而不是试图理解 switch . 我还看到了一些噩梦般的 switch 语句,其中许多案例构造不佳,只是试图遵循所有逻辑,许多失败案例分散在各处,而许多案例并非如此,变得困难......哪种导致我谈到的第一个/冗余问题。
从理论上讲,if/else 构造可能存在相同的问题,但实际上这似乎并不经常发生。也许(只是猜测)程序员被迫更仔细地阅读,因为您需要了解在 if/else 构造中测试的通常更复杂的条件?如果您正在编写一些您知道其他人可能永远不会触及的简单内容,并且您可以很好地构建它,那么我想这是一个折腾。在这种情况下,任何更具可读性和对您来说感觉最好的东西都可能是正确的答案,因为您可能会维持该代码。
Switch 语句通常比 if-else 结构执行得更快(但并非总是如此)。由于 switch 语句的可能值是预先安排好的,编译器能够通过构建跳转表来优化性能。不必像在 if/else 构造中那样测试每个条件(好吧,直到找到正确的条件为止)。
然而,情况并非总是如此。如果您有一个简单的开关,例如,可能值为 1 到 10,就会出现这种情况。添加的值越多,跳转表就越大,switch 的效率就越低(不是 if/else,但比相对简单的 switch 语句效率低)。此外,如果这些值变化很大(即,不是 1 到 10,而是有 10 个可能的值,例如 1、1000、10000、100000 等到 100000000000),则切换的效率低于更简单的情况.
希望这可以帮助。
每次对单个变量有超过 2 个条件时使用 switch,以工作日为例,如果每个工作日都有不同的操作,则应该使用 switch。
其他情况(多个变量或复杂的 if 子句,您应该使用 If,但没有关于在何处使用每个的规则。
由于打字需要更长的时间而避免使用东西的倾向是一件坏事,请尝试将其根除。也就是说,过于冗长的东西也很难阅读,所以小而简单很重要,但重要的是可读性而不是可写性。简洁的单行通常比布局良好的 3 或 4 行更难阅读。
使用最能描述操作逻辑的构造。
我个人更喜欢在太多嵌套的 if-else 中看到 switch 语句,因为它们更容易阅读。开关在显示状态方面的可读性也更好。
另请参阅这篇文章中关于pacman ifs的评论。
这在很大程度上取决于具体情况。最好,我认为如果switch
有if-else
很多嵌套的if-elses
.
问题是多少是多少?
昨天我也在问自己同样的问题:
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 语句(2-3 例),我会说这很好。如果看起来你最终会得到更多,我会推荐使用多态性。此处可以使用 AbstractFactory 模式来创建一个对象,该对象将执行您在开关中尝试执行的任何操作。丑陋的 switch 语句将被抽象掉,你最终会得到更干净的代码。
我经常认为使用 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
哦,如果优化不符合要求,请使用新的编译器或语言...
Switch 语句更容易阅读和维护。并且通常更快,更不容易出错。