Pytanie Zakres zmiennej w obudowie przełącznika [duplikat]


To pytanie już zawiera odpowiedź:

Myślę, że nie rozumiem, jak zakres działa w przypadku przełącznika.

Czy ktoś może mi wyjaśnić, 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 Przypadek 1?

Jeśli pominę deklarację przypadku 1, zmienna "str" ​​nigdy nie zostanie zadeklarowana ...


76
2017-10-08 20:36


pochodzenie




Odpowiedzi:


Powtórzę to, co powiedzieli inni: zakres zmiennych w każdym z nich case Klauzula odpowiada całości switch komunikat. Można jednak tworzyć kolejne zagnieżdżone zasięgi za pomocą nawiasów klamrowych w następujący sposób:

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

Wynikowy kod zostanie teraz skompilowany pomyślnie od nazwy zmiennej str w każdym case Klauzula jest w swoim własnym zakresie.


140
2017-10-08 20:49



Posłuchaj tego faceta. On ma rację. - John
Poprawny. 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 przypadku (jeśli nie było dla return) "kontynuuje" nawet po nawiasie zamykającym - i pomaga zapomnieć break. - leonbloy
Użyj również break dla łatwości konserwacji i zapobiegania błędom! nawet jeśli nie jest to wymagane. - worenga
@mightyuhu break nie zadziała, ponieważ jest instrukcja return ... przynajmniej dla Java ... C lub C ++ jest w porządku ... - Boy
@Boy masz prawdopodobnie rację. Jednak nie był to właściwie mój pierwotny punkt. Myślę, że te przedwczesne zwroty prowadzą do wszelkiego rodzaju problemów związanych z utrzymaniem i błędami, nie wspominając o martwym kodzie lub złożoności cyklicznej. Tak więc, jako ogólna rada, należy unikać takich konstrukcji, przynajmniej w przypadkach, które nie są trywialne - worenga


Zakres zmiennej to całość switch oświadczenie - wszystkie przypadki i domyślne, jeśli są uwzględnione.

Oto kilka innych opcji ...

Opcja 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;
}

9
2017-10-08 20:40





Wydajesz się zakładać, że każdy case jest blokiem o własnym zasięgu lokalnym, tak jak blok / else. To nie jest.

Ważne jest, aby skorygować ten błąd koncepcyjny, ponieważ w przeciwnym razie skończysz w częstej pułapce zapomnienia break w środku case


8
2017-10-08 20:43





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

na przykład 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.


2
2017-12-14 10:55





Kilka przypadków można wykonać w jednym poleceniu switch. Więc..


0
2017-10-08 20:40





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).


0
2017-10-08 20:41





W pierwszym przypadku zakres deklaracji String znajduje się wewnątrz instrukcji switch, dlatego jest pokazywany jako duplikat, podczas gdy w drugim łańcuch jest zamknięty w nawiasy klamrowe, co ogranicza zakres w warunkach if / else, dlatego nie jest to błąd w drugi przypadek.


0
2017-10-08 20:43