什么是 `switch` 语句?
what are `switch` statements for?
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();
}
如果需要,Plus if
可让您进行不等式比较(>
、<
、!=
)。我可能会发现 switch 更有用的唯一情况是当你不在内部使用 break
语句时:但这种情况并不经常发生,而且我发现它在代码质量方面很糟糕。
我真的找不到使用 switch
优于 if
的任何好处...那么为什么要定义它?
一些语言也允许在 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
上更难分析的优化,例如使用二进制搜索来确定正确的大小写而不是线性搜索,甚至使用跳转 table 或算术。例如。下面的开关
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
。是的,与更通用的构造相比,结构化编程构造在它们可以表达的内容上是严格劣等的。但它们更具可读性,使意图更清晰,并且往往更安全,更易于维护。
switch
是一个非常低级的语句,从某种意义上说 case
语句中的代码被编译成内存中的连续指令块,它只是有条件地跳入(取决于当然,在所讨论的语言上,现代高级语言在幕后的行为可能大不相同)。这也是为什么你有失败行为的原因,一旦确定了起始地址,就会执行所有后续指令,除非中断。
所以最初这是一种非常自然的方式来跳过或进入指令块。许多语言都采用了 switch
语句,很多可能是因为熟悉,但也有很多可能是因为它 是 在某些情况下确实相当可读,例如:
switch (someComplicatedCalculation($foo, $bar)) {
case CONSTANT_A:
...
case CONSTANT_B:
...
...
}
这是一种非常简洁的表达方式,尤其是当您可能还依赖于掉落行为时。
当然,其他语言从未采用过switch
,例如Python,并要求使用 if..elif..else
。最后,您可以使用任何一种语言构造编写类似的代码,这取决于您。
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();
}
如果需要,Plus if
可让您进行不等式比较(>
、<
、!=
)。我可能会发现 switch 更有用的唯一情况是当你不在内部使用 break
语句时:但这种情况并不经常发生,而且我发现它在代码质量方面很糟糕。
我真的找不到使用 switch
优于 if
的任何好处...那么为什么要定义它?
一些语言也允许在 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
上更难分析的优化,例如使用二进制搜索来确定正确的大小写而不是线性搜索,甚至使用跳转 table 或算术。例如。下面的开关
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
。是的,与更通用的构造相比,结构化编程构造在它们可以表达的内容上是严格劣等的。但它们更具可读性,使意图更清晰,并且往往更安全,更易于维护。
switch
是一个非常低级的语句,从某种意义上说 case
语句中的代码被编译成内存中的连续指令块,它只是有条件地跳入(取决于当然,在所讨论的语言上,现代高级语言在幕后的行为可能大不相同)。这也是为什么你有失败行为的原因,一旦确定了起始地址,就会执行所有后续指令,除非中断。
所以最初这是一种非常自然的方式来跳过或进入指令块。许多语言都采用了 switch
语句,很多可能是因为熟悉,但也有很多可能是因为它 是 在某些情况下确实相当可读,例如:
switch (someComplicatedCalculation($foo, $bar)) {
case CONSTANT_A:
...
case CONSTANT_B:
...
...
}
这是一种非常简洁的表达方式,尤其是当您可能还依赖于掉落行为时。
当然,其他语言从未采用过switch
,例如Python,并要求使用 if..elif..else
。最后,您可以使用任何一种语言构造编写类似的代码,这取决于您。