简体   繁体   English

开关盒中的 OR 运算符?

[英]OR operator in switch-case?

Let's take a simple switch-case that looks like:让我们看一个简单的 switch-case,如下所示:

@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.someValue :
        case R.id.someOtherValue:
            // do stuff
            break;
    }
}

I wonder why it is not allowed to use the ||我想知道为什么不允许使用|| operator?操作员? Like喜欢

switch (v.getId()) {
    case R.id.someValue || R.id.someOtherValue:
        // do stuff
        break;
}

The switch-case construct is pretty similar to an if-else statement, you can use the OR operator in an if however. switch-case结构与if-else语句非常相似,但是您可以在if中使用 OR 运算符。 What are the backgrounds for a switch-case to not accept this operator? switch-case不接受此运算符的背景是什么?

dude do like this伙计喜欢这样

    case R.id.someValue :
    case R.id.someOtherValue :
       //do stuff

This is same as using OR operator between two values Because of this case operator isn't there in switch case这与在两个值之间使用 OR 运算符相同因为这种情况运算符在 switch case 中不存在

What are the backgrounds for a switch-case to not accept this operator? switch-case 不接受此运算符的背景是什么?

Because case requires constant expression as its value.因为case需要常量表达式作为它的值。 And since an ||并且由于|| expression is not a compile time constant, it is not allowed.表达式不是编译时常量,这是不允许的。

From JLS Section 14.11 :JLS 第 14.11 节

Switch label should have following syntax:开关标签应具有以下语法:

SwitchLabel:开关标签:
case ConstantExpression :案例常量表达式:
case EnumConstantName :案例 EnumConstantName :
default :默认 :


Under the hood:引擎盖下:

The reason behind allowing just constant expression with cases can be understood from the JVM Spec Section 3.10 - Compiling Switches :可以从JVM Spec 第 3.10 节 - 编译开关中了解仅允许使用 case 进行常量表达式的原因:

Compilation of switch statements uses the tableswitch and lookupswitch instructions. switch 语句的编译使用tableswitchlookupswitch指令。 The tableswitch instruction is used when the cases of the switch can be efficiently represented as indices into a table of target offsets.当切换的情况可以有效地表示为目标偏移表中的索引时,使用 tableswitch 指令。 The default target of the switch is used if the value of the expression of the switch falls outside the range of valid indices.如果 switch 表达式的值超出有效索引的范围,则使用 switch 的默认目标。

So, for the cases label to be used by tableswitch as a index into the table of target offsets, the value of the case should be known at compile time.因此,对于tableswitch使用的 case 标签作为目标偏移表的索引,case 的值应该在编译时知道。 That is only possible if the case value is a constant expression.这只有在 case 值是一个常量表达式时才有可能。 And |||| expression will be evaluated at runtime, and the value will only be available at that time.表达式将在运行时评估,并且该值仅在那时可用。

From the same JVM section, the following switch-case :从同一 JVM 部分,以下switch-case

switch (i) {
    case 0:  return  0;
    case 1:  return  1;
    case 2:  return  2;
    default: return -1;
}

is compiled to:编译为:

0   iload_1             // Push local variable 1 (argument i)
1   tableswitch 0 to 2: // Valid indices are 0 through 2  (NOTICE This instruction?)
      0: 28             // If i is 0, continue at 28
      1: 30             // If i is 1, continue at 30
      2: 32             // If i is 2, continue at 32
      default:34        // Otherwise, continue at 34
28  iconst_0            // i was 0; push int constant 0...
29  ireturn             // ...and return it
30  iconst_1            // i was 1; push int constant 1...
31  ireturn             // ...and return it
32  iconst_2            // i was 2; push int constant 2...
33  ireturn             // ...and return it
34  iconst_m1           // otherwise push int constant -1...
35  ireturn             // ...and return it

So, if the case value is not a constant expressions, compiler won't be able to index it into the table of instruction pointers, using tableswitch instruction.因此,如果case值不是常量表达式,编译器将无法使用tableswitch指令将其索引到指令指针表中。

You cannot use ||你不能使用 || operators in between 2 case.运算符介于 2 种情况之间。 But you can use multiple case values without using a break between them.但是您可以使用多个 case 值,而无需在它们之间使用中断。 The program will then jump to the respective case and then it will look for code to execute until it finds a "break".然后程序将跳转到相应的案例,然后它会寻找要执行的代码,直到找到“中断”。 As a result these cases will share the same code.因此,这些案例将共享相同的代码。

switch(value) 
{ 
    case 0: 
    case 1: 
        // do stuff for if case 0 || case 1 
        break; 
    // other cases 
    default: 
        break; 
}

I do not know a best approach but I do it as我不知道最好的方法,但我这样做

case 'E':
case 'e':
   System.exit(0);
   break;

Switch is not same as if-else-if. Switch 与 if-else-if 不同。

Switch is used when there is one expression that gets evaluated to a value and that value can be one of predefined set of values.当有一个表达式被评估为一个值并且该值可以是预定义的一组值之一时,使用 Switch。 If you need to perform multiple boolean / comparions operations run-time then if-else-if needs to be used.如果您需要在运行时执行多个布尔/比较操作,则需要使用 if-else-if。

You can still do it like this.你仍然可以这样做。

switch (v.getId()) {
    case R.id.someValue: case R.id.someOtherValue:
        // do stuff
        break;
}
foreach (array('one', 'two', 'three') as $v) {
    switch ($v) {
        case (function ($v) {
            if ($v == 'two') return $v;
            return 'one';
        })($v):
            echo "$v min \n";
            break;


    }
}

this works fine for languages supporting enclosures这适用于支持外壳的语言

helps in some cases.在某些情况下有帮助。

switch(true){
 case a == b: break;
 case a == 2 || a == 3: break;
 default: break;
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM