hombredroide
Tomemos un caso de interruptor simple que se parece a:
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.someValue :
case R.id.someOtherValue:
// do stuff
break;
}
}
Me pregunto por qué no está permitido usar el ||
¿operador? Me gusta
switch (v.getId()) {
case R.id.someValue || R.id.someOtherValue:
// do stuff
break;
}
los switch-case
construcción es bastante similar a un if-else
instrucción, puede utilizar el operador OR en una if
sin embargo. ¿Cuáles son los antecedentes para un switch-case
para no aceptar este operador?
amigo haz esto
case R.id.someValue :
case R.id.someOtherValue :
//do stuff
Esto es lo mismo que usar el operador OR entre dos valores. Debido a este caso, el operador no está allí en el cambio de caso.
-
Hola, @BalusC, esta respuesta realmente me ayudó con mi solicitud, por lo que sugiero mantener esta “respuesta”.
– vaso de
20 de marzo de 2019 a las 18:44
-
Fantástica solución.
– Stephan Bakkelund Valois
7 de noviembre de 2020 a las 16:43
Rohit jainista
¿Cuáles son los antecedentes para que un switch-case no acepte este operador?
Porque case
requiere expresión constante como su valor. Y desde un ||
expresión no es una constante de tiempo de compilación, no está permitida.
La etiqueta del interruptor debe tener la siguiente sintaxis:
Cambiar etiqueta:
caso ExpresiónConstante:
caso EnumConstantName:
defecto :
Bajo el capó:
La razón detrás de permitir sólo la expresión constante con los casos se puede entender a partir de la JVM Spec Sección 3.10 – Compilación de conmutadores:
La compilación de sentencias switch utiliza el interruptor de mesa y cambio de búsqueda instrucciones. La instrucción tableswitch se usa cuando los casos del cambio pueden representarse eficientemente como índices en una tabla de compensaciones objetivo. El objetivo predeterminado del cambio se usa si el valor de la expresión del cambio cae fuera del rango de índices válidos.
Entonces, para que la etiqueta de casos sea utilizada por tableswitch
como un índice en la tabla de compensaciones de destino, el valor del caso debe conocerse en el momento de la compilación. Eso solo es posible si el valor del caso es una expresión constante. Y ||
expresión se evaluará en tiempo de ejecución y el valor solo estará disponible en ese momento.
Desde la misma sección de JVM, lo siguiente switch-case
:
switch (i) {
case 0: return 0;
case 1: return 1;
case 2: return 2;
default: return -1;
}
se compila a:
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
Entonces, si el case
el valor no es una expresión constante, el compilador no podrá indexarlo en la tabla de punteros de instrucción, usando tableswitch
instrucción.
-
Tengo la sensación de que el autor de la pregunta lo sabe, pero se pregunta por qué se aplica esta restricción para empezar.
– Adam Spurgin
23 de agosto de 2013 a las 22:45
-
@ Maver1ck Probablemente porque no es necesario, ya que solo puede usar el fall-through. Aunque, esto está permitido (y llevado al extremo absurdo) en Scala.
– arshajii
23 de agosto de 2013 a las 22:47
-
@ Maver1ck Podría ser útil modificar la pregunta para indicar que sabe cómo se supone que debe hacerlo dentro de la sintaxis dada, pero se pregunta por qué esta no es una alternativa aceptable
–Dennis Meng
23 de agosto de 2013 a las 22:47
-
@ Maver1ck “dado que una expresión no es una constante de tiempo de compilación, no está permitida”. debido a esto, puede ejecutarse más rápido a través de una optimización del compilador más sencilla en muchos casos. Es más rápido que si las declaraciones debido a los trucos y la magia de bajo nivel.
– progrenhard
23 de agosto de 2013 a las 22:48
-
@ Maver1ck: También vale la pena señalar que
R.id.foo || R.id.bar
no significa nada, en ningún contexto (asumiendofoo
ybar
no sonboolean
).–Oliver Charlesworth
23 de agosto de 2013 a las 23:08
Hilaj
No puedes usar || operadores entre 2 casos. Pero puede usar múltiples valores de caso sin usar un descanso entre ellos. El programa luego saltará al caso respectivo y luego buscará código para ejecutar hasta que encuentre un “descanso”. Como resultado, estos casos compartirán el mismo código.
switch(value)
{
case 0:
case 1:
// do stuff for if case 0 || case 1
break;
// other cases
default:
break;
}
-
Nunca lo había pensado así, interesante forma de hacerlo.
– serraosays
11 de abril de 2019 a las 3:18
-
O también puede usar así, caso 0, 1: //si el caso 0 || 1
– Hilaj
29 de mayo de 2019 a las 10:46
-
Esta debería ser la respuesta correcta. incluso el estudio de Android mostrará una sugerencia para fusionarse con una rama duplicada
– Libín Thomas
20 de septiembre de 2019 a las 9:34
-
Java 14 tiene una nueva declaración de cambio con sintaxis como
case 0, 1 -> ...
que puede evaluar una expresión, ejecutar un bloque de código o lanzar.– usuario904963
24 de noviembre de 2021 a las 22:17
No sé cuál es el mejor enfoque, pero lo hago como
case 'E':
case 'e':
System.exit(0);
break;
Switch no es lo mismo que if-else-if.
El cambio se usa cuando hay una expresión que se evalúa como un valor y ese valor puede ser uno de un conjunto de valores predefinido. Si necesita realizar múltiples operaciones booleanas/comparaciones en tiempo de ejecución, entonces debe usar if-else-if.
dave lee
Todavía puedes hacerlo así.
switch (v.getId()) {
case R.id.someValue: case R.id.someOtherValue:
// do stuff
break;
}
Breimer
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;
}
}
esto funciona bien para idiomas que admiten gabinetes
@OliCharlesworth sí. Revisa mi comentario para ver la respuesta de arshajii.
– Droideman
23 de agosto de 2013 a las 22:45
arshajii no parece tener una respuesta…
–Dennis Meng
23 de agosto de 2013 a las 22:46
||
es esencialmente la operación predeterminada de una declaración de caso en ausencia debreak
.– Trevor Freeman
23/08/2013 a las 22:50
Piénselo de esta manera: si Switch tuviera la misma capacidad que if-else, ¿por qué necesitamos ambos? ¡¡Será redundante!! La idea de cambiar es mejorar la legibilidad en lugar de escribir código espagueti con múltiples bloques if else. Podría decirse que el interruptor también ofrece un rendimiento ligeramente mejor debido a su simplicidad.
– Serotonin Chase
23 de agosto de 2013 a las 22:54
El idioma Ada hace exactamente el tipo de cosas que estás preguntando: dirías
when Some_Value | Some_Other_Value =>
en uncase
declaración. Pero el lenguaje no usa | como operador, por lo que no hay forma de que esta sintaxis sea ambigua. Usando || para este propósito en C (Java, etc.) haría que la sintaxis fuera ambigua, y no es una buena idea tener reglas raras con excepciones (como || significa una cosa en una expresión excepto que significa algo diferente en un contexto diferente. ..).– ajb
23 de agosto de 2013 a las 23:28