Language agnostic “switch”语句用于什么?

Language agnostic “switch”语句用于什么?,language-agnostic,switch-statement,Language Agnostic,Switch Statement,Switch语句:我知道它们是做什么的——按照惯例,当我想根据枚举的值做不同的事情时,我经常使用它们,但现在我突然想到:我们为什么要使用它最初的目的是什么?我的意思是: switch(myVar) { case Foo: doSomething(); break; case Bar: doSomethingElse(); break; default: justAnotherThing();

Switch语句:我知道它们是做什么的——按照惯例,当我想根据枚举的值做不同的事情时,我经常使用它们,但现在我突然想到:我们为什么要使用它最初的目的是什么?我的意思是:

switch(myVar) {
    case Foo:
        doSomething();
        break;
    case Bar:
        doSomethingElse();
        break;
    default:
        justAnotherThing();
        break;
}
具有与以下行为完全相同的行为:

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

加上
如果
允许进行不平等比较(
一些语言也允许在
switch
语句中进行不平等比较,例如Visual Basic:

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

然而,一般来说,
开关
在比较单个值和有限选项集的常见情况下更容易阅读。此外,它使编译器能够进行某些优化,这些优化在
if
/
else if
上更难分析,例如使用二进制搜索来确定正确的大小写而不是行ar搜索,甚至使用跳转表或算术。例如,以下开关

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]();
}
Action[]操作={
()=>{/*使用0*/}执行某些操作,
()=>{/*用1*/}做点什么,
()=>{/*用2*/}做点什么,
...
};

如果(x>=0&&x某些语言也允许在
switch
语句中进行不平等比较,例如Visual Basic:

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

然而,一般来说,
开关
在比较单个值和有限选项集的常见情况下更容易阅读。此外,它使编译器能够进行某些优化,这些优化在
if
/
else if
上更难分析,例如使用二进制搜索来确定正确的大小写而不是行ar搜索,甚至使用跳转表或算术。例如,以下开关

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]();
}
Action[]操作={
()=>{/*使用0*/}执行某些操作,
()=>{/*用1*/}做点什么,
()=>{/*用2*/}做点什么,
...
};

如果(x>=0&&x
switch
是一个相当低级的语句,那么
case
语句中的代码被编译成内存中的连续指令块,该指令块只是有条件地跳转到内存中(当然,这取决于所讨论的语言,现代高级语言在幕后的行为可能会有很大的不同)。这也是为什么你会有漏洞百出的行为,一旦确定了起始地址,所有下面的指令都会执行,除非中断

因此,最初跳转或跳入指令块是一种非常自然的方式。许多语言都采用了
switch
语句,很多可能是因为熟悉,但也有很多可能是因为在某些情况下它确实可读性很强,例如:

switch (someComplicatedCalculation($foo, $bar)) {
    case CONSTANT_A:
        ...
    case CONSTANT_B:
        ...
    ...
}
这是一种非常简洁的表达方式,特别是如果你可能还依赖于失败行为的话


当然,其他语言从来没有采用过
switch
,例如Python,而是要求使用
if..elif..else
。最终,您可以使用任何一种语言构造编写类似的代码,这取决于您。

switch
是一个相当低级的语句,因为
案例中的代码是ts被编译成内存中的连续指令块,这些指令块只是有条件地跳转到内存中(当然,这取决于所讨论的语言,现代高级语言在后台的行为可能会大不相同)。这也是为什么您会有漏掉行为,一旦确定了起始地址,除非中断,否则将执行以下所有指令

因此,最初跳转或跳入指令块是一种非常自然的方式。许多语言都采用了
switch
语句,很多可能是因为熟悉,但也有很多可能是因为在某些情况下它确实可读性很强,例如:

switch (someComplicatedCalculation($foo, $bar)) {
    case CONSTANT_A:
        ...
    case CONSTANT_B:
        ...
    ...
}
这是一种非常简洁的表达方式,特别是如果你可能还依赖于失败行为的话


当然,其他语言从来没有采用过
switch
,例如Python,而是要求使用
if..elif..else
。最后,你可以使用任何一种语言构造编写类似的代码,这取决于你。

现在,用同样的
if-else-if
链接十个或二十个选项,你会发现它不太容易阅读此外,编译器可能能够将
开关
优化为一个简单的跳转表,而不必计算每个条件,直到找到“匹配”。记住,在类似C的语言中(您似乎将其用作基础)如果没有<代码>中断<代码>,则在下面的< <代码> > <代码> >下,在<代码>中更难做到,否则如果链。对于读取能力,我认为它们几乎是一致的——只要您保持一致的IDAcess,并且使用“代码”>如果“< /代码>”,您将使用<代码>开关< /代码>,作为<代码> }。如果(myVar==
始终占用相同的空间将使所有可能的值对齐且易于阅读。在我的问题中,我确实提到了通过删除
break
来实现的下降行为,但这对可读性来说是可怕的:因此,您可能会遇到跳到下一个的案例,并且改变案例的顺序会影响行为。我只会用这个“把戏”对一个开关进行
比较,并尽量避免使用其他方法。现在,如果使用十个或二十个备选方法来进行相同的
if else if
链,您会发现它的可读性不高。此外,编译器可能能够将
开关优化为一个简单的跳转表,而不必在它找到了一个“匹配”。记住,在C语言中,如果没有“代码”>“破译<代码> >,在下面的< <代码> < <代码> >下,情况会在下一个<代码>案例> >代码>。如果< < /代码>链,那就更难做到。至于读能力,我认为它们几乎是一致的——只要你保持一致。