Dlaczego wszyscy mówią mi, że pisanie takiego kodu jest złą praktyką?
if (foo)
Bar();
//or
for(int i = 0 i < count; i++)
Bar(i);
Moim największym argumentem za pominięciem nawiasów klamrowych jest to, że czasami może zawierać dwa razy więcej wierszy. Na przykład, oto kod do malowania efektu blasku dla etykiety w C #.
using (Brush br = new SolidBrush(Color.FromArgb(15, GlowColor)))
{
for (int x = 0; x <= GlowAmount; x++)
{
for (int y = 0; y <= GlowAmount; y++)
{
g.DrawString(Text, this.Font, br, new Point(IconOffset + x, y));
}
}
}
//versus
using (Brush br = new SolidBrush(Color.FromArgb(15, GlowColor)))
for (int x = 0; x <= GlowAmount; x++)
for (int y = 0; y <= GlowAmount; y++)
g.DrawString(Text, this.Font, br, new Point(IconOffset + x, y));
Możesz także uzyskać dodatkową korzyść z łączenia w łańcuch usings
bez konieczności wciskania milion razy.
using (Graphics g = Graphics.FromImage(bmp))
{
using (Brush brush = new SolidBrush(backgroundColor))
{
using (Pen pen = new Pen(Color.FromArgb(penColor)))
{
//do lots of work
}
}
}
//versus
using (Graphics g = Graphics.FromImage(bmp))
using (Brush brush = new SolidBrush(backgroundColor))
using (Pen pen = new Pen(Color.FromArgb(penColor)))
{
//do lots of work
}
Najczęstszy argument za nawiasami klamrowymi dotyczy programowania konserwacyjnego i problemów, które wynikną z wstawienia kodu między oryginalną instrukcję if a jej zamierzonym wynikiem:
if (foo)
Bar();
Biz();
Pytania:
- Czy źle jest chcieć używać bardziej zwartej składni, jaką oferuje język? Ludzie, którzy projektują te języki, są sprytni, nie wyobrażam sobie, żeby umieścili funkcję, która zawsze jest niewłaściwa.
- Powinniśmy czy nie powinniśmy napisać kod tak, aby najniższy wspólny mianownik mógł go zrozumieć i nie miał z nim problemów?
- Czy jest inny argument, którego mi brakuje?
Odpowiedzi:
Właściwie jedyny raz, kiedy naprawdę mnie ugryzł, to debugowanie i skomentowanie bar ():
Poza tym zwykle używam:
Który załatwia powyższy przypadek.
EDYCJA Dziękuję za wyjaśnienie pytania, zgadzam się, nie powinniśmy pisać kodu do najniższego wspólnego mianownika.
źródło
Szybkość czytania ...
Oprócz tego, co już zostało wspomniane. W tym momencie zostałem już uwarunkowany analizowaniem instrukcji if z nawiasami klamrowymi i spacjami. Przeczytałem więc:
Nieco szybciej niż czytałem:
Czytam to trochę wolniej, jeśli wygląda to tak:
Czytam to znacznie wolniej niż poprzedni:
ponieważ nie mogę się powstrzymać od przeczytania go ponownie na wszelki wypadek i zastanawiam się, czy autor miał zamiar:
Omówiono już ogólnie, ale jeśli chodzi o przeczytanie poniżej, będę się temu przyglądać przez dłuższy czas, aby upewnić się, co zamierzał autor. Może nawet wytropię oryginalnego autora, aby to potwierdzić.
źródło
Jeśli to coś małego, napisz to tak:
Jeśli jest wystarczająco długi, aby podzielić na dwie linie, użyj nawiasów klamrowych.
źródło
Uważałem też, że lepiej jest używać szelek tylko wtedy, gdy są naprawdę potrzebne. Ale już nie, główny powód, dla którego masz dużo kodu, czyni go bardziej czytelnym i możesz szybciej przeanalizować kod, jeśli masz spójny styl nawiasów klamrowych.
Innym dobrym powodem, dla którego zawsze należy używać nawiasów klamrowych, poza tym, że ktoś dodaje drugą instrukcję do if, może się zdarzyć coś takiego:
Czy zauważyłeś, że klauzula else jest faktycznie klauzulą „if (b)”? Prawdopodobnie tak, ale czy zaufałbyś komuś, kto znał ten chwyt?
Tak więc, jeśli tylko dla spójności i ponieważ nigdy nie wiesz, jakie nieoczekiwane rzeczy mogą się wydarzyć, gdy ktoś inny (to zawsze inni są głupi) zmieni kod, zawsze umieszczam nawiasy klamrowe, ponieważ sprawia, że kod źródłowy jest bardziej czytelny, szybszy do przeanalizowania przez Twój mózg. Tylko w przypadku najprostszych instrukcji if, takich jak if, w których następuje delegacja lub jest ona podobna do przełącznika, gdzie wiesz, że klauzula nigdy nie zostanie rozszerzona, pominę nawiasy klamrowe.
źródło
!a || !b
) niż z (!a
) lub bez (a && !b
) dodanych nawiasów.Nie zawsze jest to uważane za złą praktykę. W Mono projektowe Wytyczne kodowania nie sugeruje użycie nawiasów klamrowych, jeśli nie jest to konieczne. To samo dotyczy standardów kodowania GNU . Myślę, że to kwestia osobistego gustu, jak zawsze w przypadku standardów kodowania.
źródło
Linie są tanie. Moc procesora jest tania. Czas programisty jest bardzo drogi.
Z reguły, jeśli nie opracowuję jakiejś aplikacji, która ma absolutnie kluczowe znaczenie dla zasobów / szybkości, zawsze popełniłbym błąd po stronie pisania kodu, czyli
(a) Każdy inny programista może łatwo śledzić to, co robię
(b) Skomentuj określone części kodu, które mogą tego wymagać
(c) Łatwe do debugowania, jeśli coś pójdzie nie tak
(d) Łatwe do modyfikacji, jeśli zajdzie taka potrzeba w przyszłości (np. dodanie / usunięcie kodu)
Szybkość lub akademicka elegancja kodu jest drugorzędna w stosunku do tych czynników z biznesowego punktu widzenia. Nie oznacza to, że postanowiłem napisać niezgrabny lub brzydki kod, ale to jest MOJA kolejność priorytetów.
Pomijanie nawiasów klamrowych w większości przypadków sprawia, że (b), (c) i (d) są trudniejsze (uwaga nie jest jednak niemożliwa). Powiedziałbym, że używanie nawiasów klamrowych lub nie ma wpływu na (a).
źródło
Wolę przejrzystość, jaką zapewnia klamra kręcona. Wiesz dokładnie, co to znaczy i nie musisz zgadywać, czy ktoś po prostu go oszukał i zostawił (i wprowadził błąd). Pomijam je tylko wtedy, gdy umieszczam if i akcję w tej samej linii. Ja też nie robię tego zbyt często. Właściwie wolę białe spacje wprowadzone przez umieszczenie nawiasu klamrowego we własnej linii, chociaż od lat programowania w stylu K&R C, kończenie wiersza nawiasem klamrowym jest praktyką, nad którą muszę pracować, aby przezwyciężyć, jeśli IDE nie wymusza tego dla mnie.
źródło
Myślę, że to kwestia wytycznych dotyczących projektu, nad którym pracujesz, i osobistego gustu.
Zwykle pomijam je, gdy nie są potrzebne, z wyjątkiem niektórych przypadków, takich jak:
wolę
źródło
Jednym z przypadków, w których może to cię ugryźć, jest dawne makra C / C ++. Wiem, że jest to kwestia C #, ale często standardy kodowania są przenoszone bez powodu, dla którego standard został stworzony w pierwszej kolejności.
Jeśli nie jesteś bardzo ostrożny podczas tworzenia makr, możesz spowodować problemy z instrukcjami if, które nie używają {}.
Nie zrozum mnie źle, nie mówię, że zawsze powinieneś robić {} tylko po to, aby uniknąć tego problemu w C / C ++, ale z tego powodu miałem do czynienia z kilkoma bardzo dziwnymi błędami.
źródło
Zwykłem myśleć w ten sam sposób.
Aż pewnego dnia (dlaczego zawsze jest ten „jeden dzień”, który na zawsze zmienia twoje życie?) Spędzamy od 24 do 36 godzin bez debugowania kodu produkcyjnego tylko po to, by dowiedzieć się, że ktoś nie założył nawiasów klamrowych połączonych ze zmianą wyszukiwania / zamiany .
To było coś takiego.
To, co przyszło później, było
Okazuje się, że system generował 500 MB logów dziennie i zostaliśmy poproszeni o jego zatrzymanie. Flaga debugowania nie była wystarczająca, więc wyszukiwanie i zamiana println były w porządku.
Mimo to, gdy aplikacja została uruchomiona, flaga debugowania była wyłączona, a ważne polecenie „saveDayData” nigdy nie zostało wywołane.
EDYTOWAĆ
Teraz jedynym miejscem, w którym nie używam nawiasów, jest konstrukcja if / try.
Po obejrzeniu, jak robi to supergwiazda.
źródło
Mówiąc szczerze, widzę to jako:
Dobrzy programiści programują defensywnie, źli programiści nie.
Ponieważ jest kilka przykładów powyżej i moje własne podobne doświadczenia z błędami związanymi z zapominaniem aparatu ortodontycznego, nauczyłem się trudnej drogi, aby ZAWSZE ZAKŁADAĆ SZELKI.
Cokolwiek innego to wybór osobistego stylu zamiast bezpieczeństwa, a to wyraźnie złe programowanie.
Joel nawet wspomina o tym w Making Wrong Code Look Wrong
Gdy zostaniesz ugryziony przez błąd z powodu brakujących nawiasów, dowiesz się, że brakujące nawiasy wyglądają nieprawidłowo, ponieważ wiesz, że jest to potencjalne miejsce na wystąpienie kolejnego błędu.
źródło
if
instrukcja kontroluje blok, ale unikniesz potrzeby stosowania bloku w przypadkach, gdyif
instrukcja kontroluje pojedynczą akcję, a nie blok.Bardzo się cieszę, że:
Osobiście nie rozumiem dlaczego
jest bardziej czytelny.
Tak, wiersze są darmowe, ale po co przewijać strony i strony kodu, skoro rozmiar może być o połowę mniejszy?
Jeśli istnieje różnica w czytelności lub łatwości konserwacji, to oczywiście, wstaw nawiasy klamrowe ... ale w tym przypadku nie widzę powodu, aby to robić.
Poza tym zawsze będę umieszczać nawiasy klamrowe dla zagnieżdżonych ifów, w których zagnieżdżono inne
vs
jest strasznie zagmatwana, więc zawsze piszę to jako:
O ile to możliwe, używam operatorów trójskładnikowych, ale nigdy ich nie zagnieżdżam .
źródło
Zgadzam się, że „jeśli jesteś na tyle sprytny, by skłonić kogoś, by zapłacił ci za pisanie kodu, powinieneś być na tyle sprytny, aby nie polegać wyłącznie na wcięciach, aby zobaczyć przepływ kodu”.
Jednak ... błędy mogą zostać popełnione, a ten jest trudny do debugowania ... zwłaszcza jeśli przychodzisz do kodu kogoś innego.
źródło
Moja filozofia jest taka, że jeśli dzięki temu kod będzie bardziej czytelny, dlaczego nie?
Oczywiście musisz gdzieś wyznaczyć granicę, na przykład znaleźć to szczęśliwe medium między zwięzłymi i nadmiernie opisowymi nazwami zmiennych. Ale nawiasy naprawdę pozwalają uniknąć błędów i poprawiają czytelność kodu.
Można argumentować, że ludzie wystarczająco sprytni, by być programistami, będą na tyle sprytni, aby uniknąć błędów, które wynikają z instrukcji bez nawiasów klamrowych. Ale czy możesz szczerze powiedzieć, że nigdy nie wpadłeś na coś tak prostego jak błąd ortograficzny? Taka Minutia może być przytłaczająca, patrząc na duże projekty.
źródło
Zawsze są wyjątki, ale sprzeciwiłbym się pomijaniu nawiasów klamrowych tylko wtedy, gdy występuje w jednej z form:
W przeciwnym razie nie mam z tym problemu.
źródło
Czasami używam bardzo dolnego kodu (wiele instrukcji using), ale poza tym zawsze umieszczam nawiasy klamrowe. Uważam, że dzięki temu kod jest bardziej przejrzysty. Jest oczywiste z czegoś więcej niż tylko wcięcia, że instrukcja jest częścią bloku (a zatem prawdopodobnie częścią if itp.).
Widziałem
błąd mnie ugryzł (a raczej „ja i koledzy” - właściwie nie przedstawiłem błędu) raz . Stało się tak pomimo faktu, że nasze ówczesne standardy kodowania zalecały używanie wszędzie nawiasów klamrowych. Zajęło mi to zaskakująco dużo czasu - bo widzisz to, co chcesz. (To było około 10 lat temu. Może teraz znajdę to szybciej).
Oczywiście użycie nawiasu klamrowego na końcu linii zmniejsza liczbę dodatkowych linii, ale osobiście i tak nie lubię tego stylu. (Używam go w pracy i uważam, że jest mniej nieprzyjemny, niż się spodziewałem, ale nadal jest trochę nieprzyjemny.)
źródło
Jestem pod wrażeniem i pokorą, że moi rówieśnicy w tej dziedzinie programowania komputerowego (was, wielu) nie są zrażeni perspektywą potencjalnych błędów, gdy pominiesz nawiasy klamrowe w blokach jednowierszowych.
To chyba znaczy, że nie jestem mądry. Wiele razy popełniałem przy tym błędy. Debugowałem błędy innych w tym zakresie. Widziałem, jak oprogramowanie jest dostarczane z błędami z tego powodu (RDP do maszyny z VS2002 i czcionka w oknie zegarka nie będzie działać).
Jeśli spojrzę na wszystkie błędy, które popełniłem, których można było uniknąć, zmieniając styl kodowania, lista jest bardzo długa. Gdybym nie zmienił swojego podejścia w każdym z tych przypadków, prawdopodobnie nigdy nie zrobiłbym tego jako programista. Znowu, chyba nie jestem mądry. Aby to zrekompensować, przez długi czas byłem zagorzałym użytkownikiem nawiasów klamrowych na blokach jednowierszowych.
To powiedziawszy, na świecie zmieniły się pewne rzeczy, które sprawiają, że zasada „będziesz używać szelek na blokach jednowierszowych” jest dziś mniej aktualna niż wtedy, gdy Mojżesz sprowadził ją do nas:
W niektórych popularnych językach problem znika, zmuszając komputer do odczytywania wcięć, tak jak robi to programista (np. Python).
Mój edytor automatycznie formatuje dla mnie, więc szanse na wprowadzenie w błąd przez wcięcia są znacznie mniejsze.
TDD oznacza, że jeśli wprowadzę błąd, ponieważ jestem zdezorientowany przez blok jednowierszowy, znacznie bardziej prawdopodobne jest, że szybko go odkryję.
Refaktoryzacja i ekspresyjność języka powodują, że moje bloki są znacznie krótsze, a bloki jednowierszowe zdarzają się znacznie częściej niż zwykle. Hipotetycznie, przy bezwzględnym zastosowaniu ExtractMethod, mógłbym mieć tylko jednowierszowe bloki w całym moim programie. (Zastanawiam się, jak to by wyglądało?)
W rzeczywistości bezlitosna refaktoryzacja i pomijanie nawiasów klamrowych w blokach jednowierszowych może przynieść wyraźną korzyść: kiedy widzisz nawiasy klamrowe, w Twojej głowie może zadzwonić mały alarm z napisem „tu złożoność! Uwaga!”. Wyobraź sobie, że to norma:
Otwieram się na pomysł zmiany mojej konwencji kodowania na coś w rodzaju „bloki jednowierszowe mogą nigdy nie mieć nawiasów klamrowych” lub „jeśli można umieścić blok w tym samym wierszu co warunek, a wszystko mieści się w 80 znakach, pomiń nawiasy ". Zobaczymy.
źródło
Spośród trzech konwencji:
i:
i (które reprezentują dowolny styl wcięcia przy użyciu otwierającego i zamykającego nawiasu klamrowego):
Wolę ten ostatni jako:
źródło
Twoje główne argumenty przeciwko używaniu nawiasów klamrowych to fakt, że używają one dodatkowych wierszy i wymagają dodatkowego wcięcia.
Linie są (prawie) wolne, więc minimalizacja liczby wierszy w kodzie nie powinna być celem.
Wcięcie jest niezależne od użycia nawiasów klamrowych. W twoim kaskadowym przykładzie „używania” nadal uważam, że powinieneś wcinać je, nawet jeśli pominiesz nawiasy klamrowe.
źródło
Mocno wierzę w pisanie uporządkowanego i zwięzłego kodu, ale zawsze używałbym nawiasów klamrowych. Uważam, że są one wygodnym sposobem szybkiego sprawdzenia zakresu, w którym istnieje określony wiersz kodu. Nie ma dwuznaczności, jest po prostu wyraźnie przedstawione przed tobą.
Niektórzy mogą powiedzieć, że jest to przypadek preferencji, ale uważam, że logiczny przepływ programu jest znacznie łatwiejszy do prześledzenia, jeśli jest wewnętrznie spójny, i nie uważam, że spójne jest napisanie takiej instrukcji IF;
I jeszcze jeden taki;
Wolę tylko wybrać jeden ogólny styl i się go trzymać :)
źródło
Jednym z głównych problemów jest, gdy masz regiony jednej wkładki i non-ONE wkładki wraz z oddzieleniem od statment kontrolnej (
for
,if
, co masz) i koniec statment.Na przykład:
źródło
Kiedyś byłem wielkim zwolennikiem „nawiasów klamrowych to MUSI!”, Ale od czasu przyjęcia testów jednostkowych stwierdziłem, że moje testy jednostkowe chronią instrukcje bez klamry przed scenariuszami takimi jak:
Dzięki dobrym testom jednostkowym mogę śmiało pominąć nawiasy klamrowe w przypadku prostych instrukcji, aby poprawić czytelność (tak, to może być subiektywne).
Alternatywnie, w przypadku czegoś takiego jak powyżej, prawdopodobnie wstawiłbym to tak:
W ten sposób programista, który musi dodać bar () do warunku, byłby bardziej skłonny rozpoznać brak nawiasów klamrowych i dodać je.
źródło
Skorzystaj z własnego osądu.
sam w sobie jest w porządku. Chyba że naprawdę martwisz się, że kretyni wprowadzą coś takiego później:
Jeśli nie martwisz się kretynami, nic ci nie jest (nie jestem - jeśli nie potrafią poprawnie uzyskać podstawowej składni kodu, to najmniejszy z ich problemów)>
W zamian jest dużo bardziej czytelny.
Resztę czasu:
Który był moim ulubionym, odkąd pamiętam. Do tego:
Pracuje dla mnie.
Sama przestrzeń w pionie nie jest szczególnie istotna, ale czytelność jest. Nawias otwierający w wierszu sam w sobie zatrzymuje rozmowę o element składniowy, dopóki oko nie przejdzie do następnego wiersza. Nie to, co mi się podoba.
źródło
if (parameter == null) return null;
.Okej, to jest stare pytanie, na które odpowiedziano na śmierć. Mam coś do dodania.
Najpierw muszę tylko powiedzieć, UŻYJ SZELEK. Mogą tylko pomóc w czytelności, a czytelność (dla ciebie i innych!) Powinna być bardzo wysoko na twojej liście priorytetów, chyba że piszesz asembler. Nieczytelny kod zawsze prowadzi do błędów. Jeśli okaże się, że nawiasy klamrowe powodują, że kod zajmuje zbyt dużo miejsca, Twoje metody są prawdopodobnie za długie. Większość lub wszystkie metody powinny mieścić się na jednej wysokości ekranu, jeśli robisz to dobrze, a Znajdź (F3) jest twoim przyjacielem.
Teraz do dodania: jest z tym problem:
Spróbuj ustawić punkt przerwania, który zostanie uderzony tylko wtedy, gdy bar () ma zostać uruchomiony. Możesz to zrobić w C #, umieszczając kursor w drugiej połowie kodu, ale nie jest to oczywiste i jest trochę uciążliwe. W C ++ w ogóle nie można tego zrobić. Z tego powodu jeden z naszych najstarszych programistów pracujących nad kodem C ++ nalega na podzielenie instrukcji „if” na dwie linie. I zgadzam się z nim.
Więc zrób to:
źródło
aby kod z nawiasami klamrowymi nie zajmował dużo miejsca, stosuję technikę zalecaną w książce Code Complete :
źródło
if
którym następuje pojedyncza linia z wcięciem, można wizualnie rozpoznać, że kontroluje pojedynczą instrukcję bez potrzeby stosowania nawiasów. Styl otwartego nawiasu klamrowego sam w sobie oszczędza zatem białe znaki w sytuacji, gdyif
instrukcja kontroluje coś, co jest semantycznie pojedynczą akcją (w odróżnieniu od sekwencji kroków, która zdarza się, że zawiera tylko jeden krok). Na przykładif (someCondition)
/ `throw new SomeException (...)`.Powiedzmy, że masz kod:
a potem ktoś inny podchodzi i dodaje:
Zgodnie ze sposobem zapisu, bar (); jest teraz wykonywany bezwarunkowo. Uwzględniając nawiasy klamrowe, zapobiegasz tego rodzaju przypadkowym błędom. Kod powinien być napisany w taki sposób, aby takie błędy utrudniały lub uniemożliwiały ich popełnienie. Gdybym przeglądał kod i zobaczył brakujące nawiasy klamrowe, szczególnie rozmieszczone w wielu wierszach, utworzyłbym defekt. W przypadkach, gdy jest to uzasadnione, trzymaj go w jednym wierszu, aby szansa popełnienia takiego błędu była ponownie ograniczona do minimum.
źródło
Redukcja linii nie jest dobrym argumentem za porzuceniem nawiasów klamrowych. Jeśli Twoja metoda jest zbyt duża, prawdopodobnie powinna zostać ponownie podzielona na mniejsze części lub zrestrukturyzowana. Takie postępowanie bez wątpienia zwiększy czytelność bardziej niż zwykłe zdjęcie aparatu.
źródło
Zawsze je pomijam, gdy jest to stosowne, na przykład w twoim pierwszym przykładzie. Czysty, zwięzły kod, który widzę i rozumiem, patrząc na niego, jest łatwiejszy do utrzymania, debugowania i zrozumienia niż kod, który muszę przewijać i czytać wiersz po wierszu. Myślę, że większość programistów się z tym zgodzi.
Łatwo wymknąć się spod kontroli, jeśli zaczniesz wykonywać wiele zagnieżdżeń, klauzule if / else itd., Ale myślę, że większość programistów powinna być w stanie powiedzieć, gdzie narysować linię.
Widzę to tak jakby argument dla
if ( foo == 0 )
vsif ( 0 == foo )
. Ta ostatnia może zapobiec błędom dla nowych programistów (a może nawet czasami dla weteranów), podczas gdy ta pierwsza jest łatwiejsza do odczytania i zrozumienia, gdy utrzymujesz kod.źródło
W większości przypadków jest zakorzeniony jako standard kodowania, czy to dla firmy, czy dla projektu FOSS.
Ostatecznie ktoś inny będzie musiał zagłębić się w twój kod, a każdy programista musi spędzić dużo czasu, aby dowiedzieć się, jaki jest określony styl sekcji kodu, nad którym pracuje.
Wyobraź sobie również, że ktoś przechodzi między Pythonem a językiem Cish więcej niż raz dziennie ... W Pythonie wcięcia są częścią symantyki bloków tego języka i łatwo byłoby popełnić błąd podobny do tego, który zacytowałeś.
źródło
Po stronie bezpieczniejszego - jeszcze tylko jeden błąd, którego potencjalnie nie będziesz musiał naprawiać.
Osobiście czuję się bezpieczniej, jeśli wszystkie moje bloki są owinięte w kręcone. Nawet w przypadku jednowierszowych są to proste zapisy, które łatwo zapobiegają błędom. Sprawia, że kod jest bardziej czytelny w tym sensie, że wyraźnie widzisz, co jest w bloku, aby nie mylić treści bloku z następującymi instrukcjami poza blokiem.
Jeśli mam jedną linijkę, zwykle formatuję ją w następujący sposób:
Jeśli linia jest po prostu zbyt uciążliwa, użyj następującego:
źródło