if i>0 : return sqrt(i)
elif i==0: return 0
else : return 1j * sqrt(-i)
VS
if i>0:
return sqrt(i)
elif i==0:
return 0
else:
return 1j * sqrt(-i)
Biorąc pod uwagę powyższe przykłady, nie rozumiem, dlaczego właściwie nigdy nie widzę pierwszego stylu w bazach kodu. Dla mnie zmieniasz kod w format tabelaryczny, który wyraźnie pokazuje, czego chcesz. Pierwsza kolumna może być praktycznie zignorowana. Druga kolumna określa warunek, a trzecia kolumna zawiera oczekiwane dane wyjściowe. Wydaje mi się, przynajmniej prosty, łatwy do odczytania. Jednak zawsze widzę, że ten prosty rodzaj sprawy / przełącznika pojawia się w rozszerzonym, wciętym formacie. Dlaczego? Czy ludzie uważają, że drugi format jest bardziej czytelny?
Jedynym przypadkiem, gdy może to być problematyczne, jest zmiana kodu i wydłużenie go. W takim przypadku myślę, że całkowicie rozsądne jest przeformułowanie kodu na długi, wcięty format. Czy wszyscy robią to w drugą stronę, po prostu dlatego, że zawsze tak było? Będąc adwokatem diabła, sądzę, że innym powodem może być to, że ludzie znajdują dwa różne formaty w zależności od złożoności instrukcji if / else, które są mylące? Doceniony zostanie każdy wgląd.
źródło
if
jeśli jest w tej samej linii.Odpowiedzi:
Jednym z powodów może być to, że nie używasz języków, w których jest popularny.
Kilka kontrprzykładów:
Haskell ze strażnikami i wzorami:
Erlang z wzorami:
Emacs lisp:
Generalnie widzę, że format tabeli jest dość popularny w językach funkcjonalnych (i ogólnie w oparciu o wyrażenia), podczas gdy łamanie linii jest najbardziej popularne w innych (głównie na podstawie instrukcji).
źródło
if-else
stwierdzenia są zwykle rozłożone na wiele wierszy, chociaż nie są to proste trójki.Jest bardziej czytelny. Kilka powodów, dla których:
Z chwilą, gdy spróbujesz to zrobić, ostatecznie przerobisz go na instrukcje wielowierszowe. Co oznacza, że zmarnowałeś czas!
Również ludzie nieuchronnie dodają coś takiego:
Nie trzeba tego często robić, zanim zdecydujesz, że ten format jest znacznie lepszy niż alternatywa. Ach, ale można to wszystko wstawić w jednym wierszu! Enderland umiera w środku .
Albo to:
Co jest naprawdę bardzo denerwujące. Nikt nie lubi formatować takich rzeczy.
I na koniec, rozpoczniesz świętą wojnę problemu „ile spacji dla zakładek”. To, co renderuje się doskonale na ekranie jako format tabeli, może nie renderować się na moim w zależności od ustawień.
Czytelność i tak nie powinna zależeć od ustawień IDE.
źródło
:
pozycji -> robiąc różnicę w CVS, nagle staje się trudniej zrozumieć, co się właściwie zmienia. Dotyczy to również stanu vs ciała. Posiadanie ich w osobnych wierszach oznacza, że jeśli zmienisz tylko jedną z nich, różnice wyraźnie pokażą, że zmienił się tylko warunek, a nie ciało.Jestem głęboko przekonany, że „kod jest czytany wiele razy, napisany kilka - więc czytelność jest bardzo ważna”.
Kluczową rzeczą, która pomaga mi, gdy czytam kod innych ludzi, jest przestrzeganie „normalnych” wzorców, które moje oczy są wyszkolone do rozpoznawania. Najłatwiej mogę odczytać wciętą formę, ponieważ widziałem ją tyle razy, że rejestruje się prawie automatycznie (przy niewielkim wysiłku poznawczym z mojej strony). Nie dlatego, że jest „ładniejszy” - to dlatego, że przestrzega konwencji, do których jestem przyzwyczajony. Konwencja bije „lepiej” ...
źródło
Wraz z innymi już wspomnianymi wadami układ tabelaryczny zwiększa szanse na konflikty scalania kontroli wersji wymagające ręcznej interwencji.
Gdy blok wyrównywanego tabelarycznie kodu musi zostać wyrównany, system kontroli wersji potraktuje każdy z tych wierszy jako zmodyfikowany:
Załóżmy teraz, że w międzyczasie w innej gałęzi programista dodał nową linię do bloku wyrównanego kodu:
Scalenie tego oddziału nie powiedzie się:
Gdyby modyfikowany kod nie używał wyrównania tabelarycznego, scalanie przebiegałoby automatycznie.
(Ta odpowiedź była „plagiatem” z mojego własnego artykułu zniechęcającego do wyrównania tabelarycznego w kodzie).
źródło
Formaty tabelaryczne mogą być bardzo ładne, jeśli rzeczy zawsze mieszczą się w przydzielonej szerokości. Jeśli jednak coś przekracza przydzieloną szerokość, często konieczne jest posiadanie części stołu, która nie jest wyrównana z resztą, lub dostosowanie układu wszystkiego innego w tabeli, aby pasował do długiego elementu .
Jeśli pliki źródłowe były edytowane przy użyciu programów zaprojektowanych do pracy z danymi w formacie tabelarycznym i mogących obsługiwać zbyt długie elementy przy użyciu mniejszego rozmiaru czcionki, dzieląc je na dwie linie w tej samej komórce itp., Wówczas warto zastosować tabelaryczne formatuje częściej, ale większość kompilatorów chce plików źródłowych wolnych od znaczników, które edytorzy musieliby przechowywać, aby zachować formatowanie. Używanie linii ze zmiennymi wcięciami, ale żaden inny układ nie jest tak przyjemny jak formatowanie tabelaryczne w najlepszym przypadku, ale nie powoduje prawie tyle problemów w najgorszym przypadku.
źródło
Istnieje instrukcja „switch”, która zapewnia tego rodzaju rzeczy w szczególnych przypadkach, ale myślę, że nie o to pytasz.
Widziałem, czy instrukcje w formacie tabeli, ale musi istnieć duża liczba warunków, aby było warto. 3 jeśli instrukcje najlepiej wyświetlać w tradycyjnym formacie, ale jeśli masz 20, to znacznie łatwiej jest wyświetlić je w dużym bloku, który jest sformatowany, aby był wyraźniejszy.
I jest sens: jasność. Jeśli ułatwia to dostrzeżenie (a twój pierwszy przykład nie jest łatwy do ustalenia, gdzie znajduje się: separator), sformatuj go odpowiednio do sytuacji. W przeciwnym razie trzymaj się tego, czego oczekują ludzie, ponieważ zawsze łatwiej to rozpoznać.
źródło
switch
.switch
był koniecznością.switch
jest zły, ale tworzenie słownika, a następnie wyszukiwanie go w celu wykonania trywialnych rozgałęzień, nie jest złe ...Jeśli Twoje wyrażenie jest naprawdę łatwe, większość języków programowania oferuje operator:: rozgałęziający:
Jest to krótki czytelny format tabelaryczny. Ale ważną częścią jest: na pierwszy rzut oka widzę, czym jest „ważna” akcja. To jest oświadczenie zwrotne! O wartości decydują pewne warunki.
Jeśli z drugiej strony masz gałęzie, które wykonują inny kod, uważam, że wcięcie tych bloków jest o wiele bardziej czytelne. Ponieważ teraz istnieją różne „główne” działania w zależności od instrukcji if. W jednym przypadku rzucamy, w jednym logujemy się i zwracamy lub po prostu wracamy. Istnieje inny przepływ programu w zależności od logiki, więc bloki kodu zamykają różne gałęzie i sprawiają, że są one bardziej widoczne dla programisty (np. Szybkie odczytywanie funkcji w celu uchwycenia przepływu programu)
źródło
?
i:
są trudniejsze do wykrycia niżif
/else
słowa kluczowe i / lub z powodu dodatkowego „szumu” symboli.Jak już powiedział Enderland, zakładasz, że masz tylko jeden „powrót” jako akcję i że możesz oznaczyć ten „powrót” na końcu warunku. Chciałbym podać dodatkowe szczegóły na temat tego, dlaczego to się nie powiedzie.
Nie wiem, jakie są twoje preferowane języki, ale pisałem w C od dłuższego czasu. Istnieje wiele standardów kodowania, których celem jest uniknięcie pewnych standardowych błędów kodowania poprzez niedopuszczenie konstrukcji kodu podatnych na błędy, zarówno podczas wstępnego kodowania, jak i podczas późniejszej konserwacji. Najbardziej znam MISRA-C, ale są też inne i ogólnie wszystkie mają podobne reguły, ponieważ rozwiązują te same problemy w tym samym języku.
Jednym z popularnych błędów, którym często zajmują się standardy kodowania, jest ten mały problem: -
To nie robi tego, co myślisz. Jeśli chodzi o C, jeśli x wynosi 10, wtedy wywołujesz
do_something()
, ale następniedo_something_else()
zostaje wywołany niezależnie od wartości x . Tylko akcja bezpośrednio po instrukcji „if” jest warunkowa. Może to być zamierzenie kodera, w którym to przypadku istnieje potencjalna pułapka dla opiekunów; lub może nie być to zgodne z zamierzeniami kodera, w którym to przypadku wystąpił błąd. To popularne pytanie podczas wywiadu.Rozwiązaniem w standardach kodowania jest nałożenie nawiasów klamrowych wokół wszystkich działań warunkowych, nawet jeśli są one jednowierszowe. Teraz dostaniemy
lub
a teraz działa poprawnie i jest jasne dla opiekunów.
Zauważysz, że jest to całkowicie niezgodne z twoim formatem tabeli.
Niektóre inne języki (np. Python) przyjrzały się temu problemowi i zdecydowały, że ponieważ koderzy używają białych znaków do wyjaśnienia układu, dobrym pomysłem byłoby użycie białych znaków zamiast nawiasów klamrowych. W Pythonie
uzależnia wywołania do obu
do_something()
ido_something_else()
od x == 10, podczas gdyoznacza, że tylko
do_something()
zależy od x ido_something_else()
zawsze jest wywoływane.Jest to ważna koncepcja i znajdziesz ją w kilku językach. (Po raz pierwszy zobaczyłem to w Occam2, dawno temu.) Ponownie jednak możesz łatwo zauważyć, że twój format tabeli jest niezgodny z językiem.
źródło
Układ tabelaryczny może być użyteczny w kilku ograniczonych przypadkach, ale jest kilka razy, gdy jest to użyteczne w przypadku if.
W prostych przypadkach?: Może być lepszym wyborem. W średnich przypadkach zmiana jest często lepsza (jeśli Twój język ma taką opcję). W skomplikowanych przypadkach może się okazać, że lepiej sprawdzą się tabele połączeń.
Wiele razy przy refaktoryzacji kodu przestawiałem go na tabelaryczny, aby uczynić go oczywistym. Rzadko zdarza się, że zostawiam to w ten sposób, ponieważ w większości przypadków istnieje lepszy sposób na rozwiązanie problemu po jego zrozumieniu. Czasami zabrania się tego praktyka kodowania lub standard układu, w którym to przypadku przydatny jest komentarz.
Było kilka pytań na temat
?:
. Tak, jest to operator trójskładnikowy (lub, jak lubię o tym myśleć, wartość if). przy pierwszym rumieniec ten przykład jest trochę skomplikowany?: (i nadużywanie?: nie poprawia czytelności, ale boli), ale z pewną myślą Przykład można zmienić w następujący sposób, ale myślę, że w tym przypadku przełącznik jest najbardziej czytelny rozwiązanie.źródło
if ? do stuff : do other stuff
. Takie samo zamówienie jak w przypadku if / else.Nie widzę nic złego w formacie tabeli. Osobiste preferencje, ale użyłbym trójki w następujący sposób:
Nie trzeba powtarzać za
return
każdym razem :)źródło
do_something() if condition() else do_something_else()
niecondition() ? do_something() : do_something_else()
.