Nehmen wir einen einfachen Switch-Fall, der so aussieht:
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.someValue :
case R.id.someOtherValue:
// do stuff
break;
}
}
Ich frage mich, warum es nicht erlaubt ist, die zu verwenden || Operator? Wie
switch (v.getId()) {
case R.id.someValue || R.id.someOtherValue:
// do stuff
break;
}
Das switch-case Konstrukt ist ziemlich ähnlich zu einem if-else -Anweisung können Sie den OR-Operator in einer verwenden if jedoch. Was sind die Hintergründe für a switch-case diesen Operator nicht akzeptieren?
@OliCharlesworth ja. Überprüfen Sie meinen Kommentar auf die Antwort von Arshajii
– Droidenmann
23. August 2013 um 22:45 Uhr
arshajii scheint darauf keine Antwort zu haben…
– Dennis Meng
23. August 2013 um 22:46 Uhr
|| ist im Wesentlichen die Standardoperation einer case-Anweisung in Abwesenheit von break.
– Trevor Freemann
23. August 2013 um 22:50 Uhr
Stellen Sie sich das so vor: Wenn switch die gleiche Fähigkeit wie if-else hätte, warum brauchen wir dann beide? Es wird überflüssig!! Die Idee von switch besteht darin, die Lesbarkeit zu verbessern, anstatt Spaghetti-Code mit mehreren if-else-Blöcken zu schreiben. Aufgrund seiner Einfachheit bietet Switch wohl auch eine etwas bessere Leistung.
– SerotoninChase
23. August 2013 um 22:54 Uhr
Die Ada-Sprache tut genau das, wonach Sie fragen – würden Sie sagen when Some_Value | Some_Other_Value => in einem case Aussage. Aber die Sprache verwendet nicht | als Operator, daher kann diese Syntax auf keinen Fall mehrdeutig sein. Mit || für diesen Zweck in C (Java usw.) würde die Syntax mehrdeutig machen, und es ist keine gute Idee, verrückte Regeln mit Ausnahmen zu haben (wie || bedeutet in einem Ausdruck eine Sache, außer dass es in einem anderen Kontext etwas anderes bedeutet. ..).
– ajb
23. August 2013 um 23:28 Uhr
Kumpel, mach das so
case R.id.someValue :
case R.id.someOtherValue :
//do stuff
Dies ist dasselbe wie die Verwendung des OR-Operators zwischen zwei Werten. Aus diesem Grund gibt es den Operator in switch case nicht
Hey @BalusC diese Antwort hat mir tatsächlich bei meiner Bewerbung geholfen, also schlage ich vor, diese “Antwort” zu behalten
– Tasse
20. März 2019 um 18:44 Uhr
Fantastische Lösung.
– Stephan Bakkelund Valois
7. November 2020 um 16:43 Uhr
Rohit Jain
Was sind die Hintergründe dafür, dass ein Switch-Fall diesen Operator nicht akzeptiert?
Da case erfordert einen konstanten Ausdruck als Wert. Und seit ein || Ausdruck ist keine Kompilierzeitkonstante, es ist nicht erlaubt.
Die Kompilierung von Switch-Anweisungen verwendet die Tischschalter und Nachschlageschalter Anweisungen. Der Tabellenumschaltbefehl wird verwendet, wenn die Fälle des Umschaltens effizient als Indizes in einer Tabelle von Zieloffsets dargestellt werden können. Das Standardziel des Schalters wird verwendet, wenn der Wert des Ausdrucks des Schalters außerhalb des Bereichs gültiger Indizes liegt.
Also, für die Fälle, die von verwendet werden tableswitch Als Index in die Tabelle der Ziel-Offsets sollte der Wert des Falls zur Kompilierzeit bekannt sein. Das ist nur möglich, wenn der Fallwert ein konstanter Ausdruck ist. Und || Der Ausdruck wird zur Laufzeit ausgewertet, und der Wert ist nur zu diesem Zeitpunkt verfügbar.
Aus demselben JVM-Abschnitt das Folgende switch-case:
switch (i) {
case 0: return 0;
case 1: return 1;
case 2: return 2;
default: return -1;
}
wird kompiliert zu:
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
Also, wenn die case value ist kein konstanter Ausdruck, der Compiler kann ihn nicht in die Tabelle der Anweisungszeiger indizieren, indem er verwendet tableswitch Anweisung.
Ich habe das Gefühl, dass der Fragesteller das weiß, sich aber wundert, warum diese Einschränkung überhaupt besteht.
– AdamSpurgin
23. August 2013 um 22:45 Uhr
@Maver1ck Wahrscheinlich, weil es nicht nötig ist, da Sie einfach den Fall-Through verwenden können. Obwohl dies in Scala erlaubt ist (und auf ein absurdes Extrem getrieben wird).
– arshajii
23. August 2013 um 22:47 Uhr
@Maver1ck Es kann hilfreich sein, die Frage so zu ändern, dass Sie wissen, wie Sie dies innerhalb der angegebenen Syntax tun sollen, aber Sie fragen sich nur, warum dies keine akzeptable Alternative ist
– Dennis Meng
23. August 2013 um 22:47 Uhr
@Maver1ck “Da ein Ausdruck keine Kompilierzeitkonstante ist, ist er nicht zulässig.” Aus diesem Grund kann es in vielen Fällen durch eine einfachere Compileroptimierung schneller ausgeführt werden. Es ist schneller als if-Anweisungen aufgrund von Tricks und Magie auf niedrigem Niveau.
– progrenhard
23. August 2013 um 22:48 Uhr
@Maver1ck: Es lohnt sich auch, darauf hinzuweisen R.id.foo || R.id.bar bedeutet nichts, in keinem Kontext (vorausgesetzt foo und bar sind nicht boolean).
– Oliver Charlesworth
23. August 2013 um 23:08 Uhr
Hilaj
Sie können || nicht verwenden Operatoren zwischen 2 Fall. Sie können jedoch mehrere Groß-/Kleinschreibungswerte verwenden, ohne einen Umbruch zwischen ihnen zu verwenden. Das Programm springt dann zum entsprechenden Fall und sucht dann nach auszuführendem Code, bis es einen “Bruch” findet. Infolgedessen teilen sich diese Fälle denselben Code.
switch(value)
{
case 0:
case 1:
// do stuff for if case 0 || case 1
break;
// other cases
default:
break;
}
So habe ich mir das noch nie vorgestellt, interessanter Ansatz.
– serraosays
11. April 2019 um 3:18 Uhr
Oder Sie können auch so verwenden, Fall 0, 1: //falls Fall 0 || 1
– Hilaj
29. Mai 2019 um 10:46 Uhr
Dies sollte die richtige Antwort sein. Sogar Android Studio zeigt einen Vorschlag für eine Zusammenführung mit doppeltem Zweig an
– Libin Thomas
20. September 2019 um 9:34 Uhr
Java 14 hat eine neue switch-Anweisung mit einer Syntax wie case 0, 1 -> ... die zu einem Ausdruck ausgewertet, einen Codeblock ausgeführt oder ausgelöst werden kann.
– Benutzer904963
24. November 2021 um 22:17 Uhr
Ich kenne keinen besten Ansatz, aber ich mache es so
case 'E':
case 'e':
System.exit(0);
break;
Switch ist nicht dasselbe wie if-else-if.
Switch wird verwendet, wenn es einen Ausdruck gibt, der zu einem Wert ausgewertet wird, und dieser Wert einer der vordefinierten Wertesätze sein kann. Wenn Sie zur Laufzeit mehrere boolesche / Vergleichsoperationen ausführen müssen, muss if-else-if verwendet werden.
David Lee
Du kannst es immer noch so machen.
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;
}
}
Dies funktioniert gut für Sprachen, die Gehäuse unterstützen
14311600cookie-checkODER-Operator im Schalterfall?yes
@OliCharlesworth ja. Überprüfen Sie meinen Kommentar auf die Antwort von Arshajii
– Droidenmann
23. August 2013 um 22:45 Uhr
arshajii scheint darauf keine Antwort zu haben…
– Dennis Meng
23. August 2013 um 22:46 Uhr
||
ist im Wesentlichen die Standardoperation einer case-Anweisung in Abwesenheit vonbreak
.– Trevor Freemann
23. August 2013 um 22:50 Uhr
Stellen Sie sich das so vor: Wenn switch die gleiche Fähigkeit wie if-else hätte, warum brauchen wir dann beide? Es wird überflüssig!! Die Idee von switch besteht darin, die Lesbarkeit zu verbessern, anstatt Spaghetti-Code mit mehreren if-else-Blöcken zu schreiben. Aufgrund seiner Einfachheit bietet Switch wohl auch eine etwas bessere Leistung.
– SerotoninChase
23. August 2013 um 22:54 Uhr
Die Ada-Sprache tut genau das, wonach Sie fragen – würden Sie sagen
when Some_Value | Some_Other_Value =>
in einemcase
Aussage. Aber die Sprache verwendet nicht | als Operator, daher kann diese Syntax auf keinen Fall mehrdeutig sein. Mit || für diesen Zweck in C (Java usw.) würde die Syntax mehrdeutig machen, und es ist keine gute Idee, verrückte Regeln mit Ausnahmen zu haben (wie || bedeutet in einem Ausdruck eine Sache, außer dass es in einem anderen Kontext etwas anderes bedeutet. ..).– ajb
23. August 2013 um 23:28 Uhr