Powiedzmy, że mam kod w C o takiej strukturze:
switch (something)
{
case 0:
return "blah";
break;
case 1:
case 4:
return "foo";
break;
case 2:
case 3:
return "bar";
break;
default:
return "foobar";
break;
}
Oczywiście, te break
znaki nie są konieczne, aby kod działał poprawnie, ale wygląda na to, że to zła praktyka, jeśli mi ich tam nie umieszczę.
Co myślisz? Czy można je usunąć? A może zatrzymałbyś je dla większej „poprawności”?
c
switch-statement
correctness
houbysoft
źródło
źródło
continue
lubgoto
- idiomatyczne jest używanie ich zamiastbreak
.Wybrałbym zupełnie inną taktykę. Nie RETURN w środku metody / funkcji. Zamiast tego po prostu umieść zwracaną wartość w zmiennej lokalnej i wyślij ją na końcu.
Osobiście bardziej czytelne są następujące:
String result = ""; switch (something) { case 0: result = "blah"; break; case 1: result = "foo"; break; } return result;
źródło
Osobiście usuwałbym zwroty i zachował przerwy. Użyłbym instrukcji switch, aby przypisać wartość zmiennej. Następnie zwróć tę zmienną po instrukcji switch.
Chociaż jest to kwestia sporna, zawsze uważałem, że dobry projekt i hermetyzacja oznacza jedno wejście i jedno wyjście. Znacznie łatwiej jest zagwarantować logikę i nie przegapisz przypadkowo kodu porządkującego na podstawie cyklicznej złożoności funkcji.
Jeden wyjątek: Wczesny powrót jest prawidłowy, jeśli na początku funkcji zostanie wykryty zły parametr - przed pozyskaniem jakichkolwiek zasobów.
źródło
switch
, ale niekoniecznie ogólnie najlepszy. Cóż, powiedzmy, że instrukcja switch wewnątrz funkcji poprzedza kolejne 500 wierszy kodu, który zachowuje ważność tylko w określonych przypadkachtrue
. Jaki jest sens wykonywania całego tego dodatkowego kodu w przypadkach, które nie muszą go wykonywać; czy nie lepiej jest po prostureturn
wewnątrzswitch
dla tychcase
?Zachowaj przerwy - mniej prawdopodobne jest, że napotkasz problemy, jeśli później edytujesz kod, jeśli przerwy są już na miejscu.
Powiedziawszy to, wielu (w tym ja) uważa, że powrót ze środka funkcji jest złą praktyką. W idealnym przypadku funkcja powinna mieć jeden punkt wejścia i jeden punkt wyjścia.
źródło
Usuń ich. Wracanie z
case
instrukcji jest idiomatyczne , aw przeciwnym razie jest to szum „nieosiągalnego kodu”.źródło
Usunąłbym je. W mojej książce taki martwy kod powinien być uważany za błąd, ponieważ sprawia, że robisz podwójne podejście i zadajesz sobie pytanie: „Jak mógłbym kiedykolwiek wykonać tę linię?”
źródło
Normalnie napisałbym kod bez nich. IMO, martwy kod wskazuje na niechlujstwo i / lub brak zrozumienia.
Oczywiście rozważałbym również coś takiego:
char const *rets[] = {"blah", "foo", "bar"}; return rets[something];
Edycja: nawet w przypadku edytowanego postu ten ogólny pomysł może działać dobrze:
char const *rets[] = { "blah", "foo", "bar", "bar", "foo"}; if ((unsigned)something < 5) return rets[something] return "foobar";
W pewnym momencie, zwłaszcza jeśli wartości wejściowe są rzadkie (np. 1, 100, 1000 i 10000), zamiast tego potrzebujesz rzadkiej tablicy. Możesz to zaimplementować jako drzewo lub mapę w miarę dobrze (chociaż oczywiście przełącznik nadal działa również w tym przypadku).
źródło
Powiedziałbym, że je usuń i zdefiniuj domyślną: gałąź.
źródło
Czy nie byłoby lepiej mieć tablicę z
arr[0] = "blah" arr[1] = "foo" arr[2] = "bar"
i zrobić
return arr[something];
?Jeśli chodzi o praktykę w ogóle, powinieneś zachować
break
oświadczenia w przełączniku. W przypadku, gdy nie potrzebujeszreturn
stwierdzeń w przyszłości, zmniejsza to szansę, że przejdą one do następnejcase
.źródło
Ze względu na „poprawność” dobrym pomysłem są pojedyncze wejścia, pojedyncze bloki wyjścia. Przynajmniej tak było, kiedy robiłem stopień informatyczny. Więc pewnie zadeklarowałbym zmienną, przyporządkowałbym do niej w przełączniku i wróciłbym raz na koniec funkcji
źródło
Dobrze jest je usunąć. Używanie
return
jest dokładnie scenariuszem, w którymbreak
nie powinno być używane.źródło
Ciekawy. Konsensus większości z tych odpowiedzi wydaje się być taki, że zbędne
break
stwierdzenie jest niepotrzebnym bałaganem. Z drugiej stronybreak
oświadczenie w przełączniku odczytałem jako „zamknięcie” sprawy.case
bloki, które nie kończąbreak
się na mnie, zwykle wyskakują na mnie jako potencjalny upadek przez błędy.Wiem, że tak nie jest, gdy jest
return
zamiast abreak
, ale tak właśnie moje oczy „czytają” bloki obudowy w przełączniku, więc osobiście wolałbym, aby każdycase
był sparowany zbreak
. Ale wielu kompilatorów narzeka na to, żebreak
następstworeturn
jest zbyteczne / niedostępne, a ja najwyraźniej i tak jestem w mniejszości.Więc pozbądź się
break
następującego plikureturn
.Uwaga: wszystko to ignoruje, czy naruszenie zasady pojedynczego wejścia / wyjścia jest dobrym pomysłem, czy nie. W tym zakresie mam opinię, która niestety zmienia się w zależności od okoliczności ...
źródło
Mówię, usuń je. Jeśli Twój kod jest tak nieczytelny, że musisz w nim wstawiać przerwy `` aby być po bezpiecznej stronie '', powinieneś ponownie przemyśleć swój styl kodowania :)
Zawsze też wolałem nie mieszać przerw i powrotów w instrukcji switch, ale raczej trzymać się jednego z nich.
źródło
Osobiście zwykle tracę
break
s. Prawdopodobnie jednym ze źródeł tego nawyku jest programowanie procedur okien dla aplikacji Windows:LRESULT WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_SIZE: return sizeHandler (...); case WM_DESTROY: return destroyHandler (...); ... } return DefWindowProc(hwnd, uMsg, wParam, lParam); }
Osobiście uważam to podejście za dużo prostsze, zwięzłe i elastyczne niż deklarowanie zmiennej zwracanej ustawionej przez każdy program obsługi, a następnie zwracanie jej na końcu. Biorąc pod uwagę to podejście,
break
s są zbędne i dlatego powinny odejść - nie służą żadnemu użytecznemu celowi (składniowo ani wizualnie IMO) i tylko nadymają kod.źródło
Myślę, że * przerwy * mają jakiś cel. Ma to na celu utrzymanie „ideologii” programowania. Gdybyśmy mieli po prostu „zaprogramować” nasz kod bez logicznej spójności, być może byłby czytelny dla Ciebie teraz, ale spróbuj jutro. Spróbuj wyjaśnić to swojemu szefowi. Spróbuj uruchomić go w systemie Windows 3030.
Bleah, pomysł jest bardzo prosty:
Switch ( Algorithm ) { case 1: { Call_911; Jump; }**break**; case 2: { Call Samantha_28; Forget; }**break**; case 3: { Call it_a_day; }**break**; Return thinkAboutIt?1:return 0; void Samantha_28(int oBed) { LONG way_from_right; SHORT Forget_is_my_job; LONG JMP_is_for_assembly; LONG assembly_I_work_for_cops; BOOL allOfTheAbove; int Elligence_says_anyways_thinkAboutIt_**break**_if_we_code_like_this_we_d_be_monkeys; } // Sometimes Programming is supposed to convey the meaning and the essence of the task at hand. It is // there to serve a purpose and to keep it alive. While you are not looking, your program is doing // its thing. Do you trust it? // This is how you can... // ---------- // **Break**; Please, take a **Break**;
/ * Tylko drobne pytanie. Ile kawy wypiłeś czytając powyższe? IT Czasami psuje system * /
źródło
Kod zakończenia w pewnym momencie. Zapewnia to lepszą czytelność kodu. Dodanie instrukcji return (wielokrotne wyjścia) pomiędzy nimi utrudni debugowanie.
źródło
Jeśli masz kod typu „lookup”, możesz spakować klauzulę switch-case w samej metodzie.
Mam kilka z nich w systemie „hobby”, który rozwijam dla przyjemności:
private int basePerCapitaIncomeRaw(int tl) { switch (tl) { case 0: return 7500; case 1: return 7800; case 2: return 8100; case 3: return 8400; case 4: return 9600; case 5: return 13000; case 6: return 19000; case 7: return 25000; case 8: return 31000; case 9: return 43000; case 10: return 67000; case 11: return 97000; default: return 130000; } }
(Tak. To przestrzeń GURPS ...)
Zgadzam się z innymi, że w większości przypadków należy unikać więcej niż jednego powrotu w metodzie i zdaję sobie sprawę, że ta metoda mogłaby być lepiej zaimplementowana jako tablica lub coś innego. Właśnie odkryłem, że powrót przełącznika wielkości liter jest dość łatwym dopasowaniem do tabeli odnośników z korelacją 1-1 między danymi wejściowymi a wyjściowymi, tak jak powyżej (gry fabularne są ich pełne, jestem pewien, że istnieją w innych „biznes”): D.
Z drugiej strony, jeśli klauzula case jest bardziej złożona lub coś dzieje się po instrukcji switch, nie polecałbym używania w niej return, ale raczej ustaw zmienną w przełączniku, zakończ ją przerwą i zwróć wartość zmiennej na końcu.
(Z drugiej strony… po trzecie… zawsze można zmienić sposób przełączania na jego własną metodę… Wątpię, czy będzie to miało wpływ na wydajność i nie zdziwiłbym się, gdyby współczesne kompilatory potrafiły je rozpoznać jako coś, co można by wstawić ...)
źródło