2010-10-08 17 views
71

Myślę, że nie rozumiem, w jaki sposób zakres działa w przypadku przełącznika.Zakres zmiennej w obudowie przełącznika

Czy ktoś może mi wytłumaczyć dlaczego pierwszy kod się nie kompiluje, a drugi?

Kod 1:

int key = 2; 
switch (key) { 
case 1: 
     String str = "1"; 
     return str; 
case 2: 
     String str = "2"; // duplicate declaration of "str" according to Eclipse. 
     return str; 
} 

Kod 2:

int key = 2; 
if (key == 1) { 
     String str = "1"; 
     return str; 
} else if (key == 2) { 
     String str = "2"; 
     return str; 
} 

Dlaczego zakres zmiennej "str" ​​nie jest zawarty w sprawie 1?

Jeśli pominąć deklarację przypadku 1 zmienna „str” nie jest zadeklarowana ...

Odpowiedz

137

Powtórzę to, co powiedzieli inni: zakres zmiennych w każdej klauzuli case odpowiada całemu oświadczeniu switch. Można jednak utworzyć dodatkowe zakresy zagnieżdżonych z szelkami następująco:

int key = 2; 
switch (key) { 
case 1: { 
    String str = "1"; 
    return str; 
    } 
case 2: { 
    String str = "2"; 
    return str; 
    } 
} 

Otrzymany kod będzie teraz skompilować powodzeniem od zmiennej o nazwie str w każdej klauzuli case jest we własnym zakresie.

+6

Posłuchaj tego gościa. On ma rację. – John

+21

Prawidłowo. Ale byłbym bardzo zdenerwowany przez jakiegokolwiek programistę w moim zespole, który używa tej "składni" bez bardzo dobrego powodu. To przepis na zamieszanie i błędy. To wizualnie ukrywa fakt, że pierwszy blok case (jeśli nie był dla 'return')" kontynuuje "nawet po nawiasie zamykającym - i pomaga zapomnieć o' break'. – leonbloy

+2

również: użyj 'break' dla łatwości konserwacji i zapobiegania błędom! nawet jeśli nie jest to wymagane. – worenga

9

Zakres zmiennej jest cała switch oświadczenie - wszystkie przypadki i domyślne, jeśli włączone.

Oto kilka innych opcji ...

Wariant 1:

int key = 2; 
switch (key) { 
case 1: 
    return "1"; 
case 2: 
    return "2"; 
} 

Opcja 2:

int key = 2; 
String str = null; 
switch (key) { 
case 1: 
    str = "1"; 
    return str; 
case 2: 
    str = "2"; 
    return str; 
} 
0

Kilka przypadków mogą być wykonywane w jednej instrukcji switch. Więc ..

0

Zakres zmiennej istnieje między nawiasami instrukcji switch i if. W przykładzie Kod 1 klamry przełączające obejmują zarówno deklaracje zmiennych, które spowodują błąd kompilatora, jak i nazwę już powiązaną ze zmienną.

W drugim przykładzie jest ok, ponieważ obie zmienne są deklarowane w ich własnych nawiasach klamrowych (zakres).

8

Wydaje się, że zakładasz, że każdy case jest blokiem z własnym zasięgiem lokalnym, tak jakby blokował/else. To nie jest.

Ważne jest, aby rozwiązać ten koncepcyjny błąd, ponieważ w przeciwnym razie będzie koniec spada na częste pułapkę zapominając break wewnątrz case

0

W pierwszym przypadku zakres deklaracji łańcuch jest w instrukcji switch dlatego jest pokazany jako duplikat, podczas gdy w drugim łańcuch jest zamknięty w nawiasy klamrowe, co ogranicza zakres w warunkach if/else, dlatego nie jest błędem w drugim przypadku.

2

Myślę, że jest to poprawne pytanie, a założenie zakresu dla przypadku jest nieuniknione. Dostosowując się do niego, ponieważ pisarz java uczynił to nie jest poprawne.

np.jeśli instrukcja domyślnie przyjmuje pierwszy wiersz w swoim zasięgu niż to, co jest nie tak w przypadkach, gdy koniec przypadku jest jawnie zamknięty przez instrukcję break. Stąd deklaracja w przypadku 1: nie powinna być dostępna w przypadku 2 i ma zakres równoległy, ale nie zagnieżdżony.

Powiązane problemy