什么是`switch`语句?

时间:2017-10-06 10:20:21

标签: language-agnostic switch-statement

切换语句:我知道他们做了什么 - 我按照常规使用它们很多次,正如我想根据Enum的值做不同的东西,但是现在它只是打击了我:为什么我们使用它? 它的最初目的是什么?我的意思是,这个:

switch(myVar) {
    case Foo:
        doSomething();
        break;
    case Bar:
        doSomethingElse();
        break;
    default:
        justAnotherThing();
        break;
}

具有与以下完全相同的行为:

if(myVar == Foo) {
    doSomething()
}else if(myVar == Bar) {
    doSomethingElse();
}else {
    justAnotherThing();
}

Plus if可让您根据需要进行不等式比较(><!=)。我发现交换机更有用的唯一情况是当你不使用break语句时:但这种情况不常发生,而且我觉得它在代码质量上很糟糕。

我真的找不到使用switch优于if的任何好处...那么为什么定义它?

2 个答案:

答案 0 :(得分:4)

某些语言也允许在switch语句中进行不等式比较,例如: Visual Basic:

Select Case x
  Case < 5
    // ...
  Case 7
    // ...
  Case 10 To 15
    // ...
  Case Else
    // ...
End Select

基本上,是的,switch通常可以写成if / else if阶梯,区别在于switch比较一个对于许多比较值的值,if / else if可以在每个分支中执行任何操作。但即使在所有语言中都不是这种情况,例如在PowerShell中,switch可以执行大量您通常必须使用if的内容:

switch -Regex ($x) {
  '^\d+$' {'Number'}
}

switch ($x) {
  { $_ is [int] -or $_ is [double] } {'Number'}
  { $_ is [string] } {'Text'}
}

但是,通常情况下,switch更容易阅读,以便将单个值与有限选项集进行比较。此外,它使编译器能够进行某些优化,这些优化在if / else if上难以分析,例如使用二进制搜索来确定正确的情况而不是线性搜索,甚至使用跳转表或算术。例如。以下开关

switch (x) {
  case 0:
    // Do something with 0
    break;
  case 1:
    // Do something with 1
    break;
  case 2:
    // Do something with 2
    break;
  ...
}

可以编译成等效的

Action[] actions = {
  () => { /* Do something with 0 */ },
  () => { /* Do something with 1 */ },
  () => { /* Do something with 2 */ },
  ...
};
if (x >=0 && x <= n) {
  actions[x]();
}

switch的简单性和局限性对于优化编译器在这种情况下是有用的,因为要分析以确定整体结构尝试的内容要少得多。

还有其他功能(有时可能具有可疑价值),例如Duff's device,或者能够适应其他情况(或goto任意其他情况,例如C#允许的情况。

您也可以问我们为什么我们有if语句和循环而不是仅使用goto。是的,与更一般的结构相比,结构化编程结构一个接一个地严格地低于它们可以表达的内容。但它们更具可读性,使意图更清晰,并且更安全,更易于维护。

答案 1 :(得分:2)

switch是一个非常低级的语句,因为case语句中的代码被编译成内存中的连续指令块,只是有条件地跳转到(取决于当然,现代高级语言的语言可能会有所不同。这也是为什么你有这种跌倒行为的原因,一旦确定了起始地址,只要执行所有后续指令,除非被打破。

所以最初这是跳过或进入指令块的一种非常自然的方式。许多语言采用switch语句,很多可能是由于熟悉,但很多可能也因为 在某些情况下确实相当可读,例如:

switch (someComplicatedCalculation($foo, $bar)) {
    case CONSTANT_A:
        ...
    case CONSTANT_B:
        ...
    ...
}

这是表达这一点的一种非常简洁的方式,特别是如果您可能也依赖于堕落行为。

当然,其他语言从未采用switch,例如Python,并且需要使用if..elif..else。最后,您可以使用任何一种语言构造编写类似的代码,它取决于您。