Czy „if (0 == value)…” nie wyrządza więcej szkody niż pożytku? [Zamknięte]

49

Jest to jedna z rzeczy, których najbardziej nienawidzę, kiedy widzę to w czyimś kodzie. Wiem, co to znaczy i dlaczego niektórzy robią to w ten sposób („co jeśli przypadkowo wstawię„ = ”zamiast tego?”). Dla mnie bardzo przypomina to, gdy dziecko schodzi po schodach, licząc kroki na głos.

Tak czy inaczej, oto moje argumenty przeciwko niemu:

  • Zakłóca naturalny przepływ odczytu kodu programu. My, ludzie, mówimy „jeśli wartość wynosi zero”, a nie „jeśli zero jest wartością”.
  • Nowoczesne kompilatory ostrzegają cię, gdy masz zadanie w swoim stanie, a właściwie jeśli twój stan składa się tylko z tego zadania, które, tak, i tak wygląda podejrzanie
  • Nie należy zapominać o wstawieniu podwójnego „=” podczas porównywania wartości, jeśli jesteś programistą. Równie dobrze możesz zapomnieć wpisać „!” podczas testowania nierówności.
mojuba
źródło
17
Też mnie to nie obchodzi, ale jest to dość daleko na mojej osobistej liście zwierząt domowych.
Adam Crossland,
7
A programiści czasami nie zauważają podwójnego „=”. Łatwo jest popełnić błąd i bardzo łatwo go przeoczyć.
zmiany
8
W jaki sposób nie jest to konstruktywne ani prawdziwe pytanie?
TheLQ
7
To jest zamknięte, więc oto moja krótka opinia: jak ludzie mogą pamiętać, aby pisać, 0 == valueale nie pamiętać, aby pisać ==? Mam na myśli blimey, jeśli o tym myślisz, dlaczego nie napisać go poprawnie na początek.
dr Hannibal Lecter
3
@muntoo: Według kompilatorów wiele rzeczy jest „poprawnych”, nie sądzę, że to bardzo dobry punkt odniesienia.
dr Hannibal Lecter

Odpowiedzi:

59

Ach, tak, „Warunkowe Yoda” („Jeśli zero jest wartością, wykonaj ten kod, musisz!”). Każdemu, kto twierdzi, że jest „lepszy”, zawsze wskazuję narzędzia takie jak lint (1). Ten szczególny problem został rozwiązany od późnych lat 70. Większość współczesnych języków nawet nie skompiluje wyrażenia podobnego if(x = 10), ponieważ odmawiają przymusu wynikowi przypisania do wartości logicznej.

Jak powiedzieli inni, z pewnością nie jest to problem, ale wywołuje trochę dysonansu poznawczego.

TMN
źródło
32
+1 dla „Warunków Yoda”. Właściwie to LOL na to. :)
Tabele Bobby
3
Chociaż kolejność jest w porządku, że sprzeciw wobec porównaniu do zera zamiast zwykłego logicznego obsadą if(!value).
SF.
1
Czy uważasz, że przypisania wewnątrz warunkowego są błędem?
4
„Większość współczesnych języków nawet tego nie skompiluje” Problem pojawia się, gdy używasz języka, który po cichu wymusza wynik przypisania do wartości logicznej. Najbardziej popularnym językiem, jaki mogę wymyślić, jest JavaScript. Dlatego zawsze używam warunkowych Yoda nawet w Javie, aby nie zapomnieć o tym, kiedy piszę javascript. Często przełączam się między nimi tak często, że może to stanowić problem.
Sam Hasler,
3
Czy ktoś wie o kompilatorze, który się nie skompiluje if (0 == x)?
Kristopher Ives
56

Jest wstrętny, ponieważ nakłada niewielki, ale zauważalny podatek psychiczny.

Ludzie czytają od lewej do prawej w praktycznie wszystkich językach programowania (i większości języków naturalnych).

Jeśli widzę 123 == x, sposób, w jaki analizuję to w następujący sposób:

  • 123- Więc co? niepełne informacje.
  • == - cóż, 123 to 123, po co to testować ...
  • x- ok, więc to nas martwi. Dopiero teraz mam kontekst.
  • Wróć do ponownego rozważenia 123i dlaczego x jest do niego porównywany.

Kiedy widzę x == 123parsowanie mentalne to:

  • x- Zapewnia kontekst, wiem o czym jest warunek. Mogę zignorować resztę. W oparciu o poprzedni przepływ mam dobry pomysł, dlaczego i co ma nadejść (i zdziwię się, jeśli będzie inaczej).
  • == - Tak myślałem.
  • 123 - Tak.

Zakłócenie jest niewielkie (w prostym przykładzie), ale zawsze to zauważam.

Stawianie wartości na pierwszym miejscu może być dobrym pomysłem, jeśli chcesz na nią zwrócić uwagę, np if (LAUNCH_NUKES == cmd). Zwykle nie taka jest intencja.

dbkk
źródło
5
Dokładnie. W językach naturalnych stała występuje zawsze z tego samego powodu: jeśli światło jest czerwone ...
mojuba,
2
@mojuba To prawda, to prawie uniwersalne. Co dziwne, istnieje kilka języków naturalnych, w których obiekt znajduje się przed tematem (kolejność OVS / OSV), ale wszystkie są niejasne.
dbkk,
1
Z drugiej strony niektórzy z nas mają tendencję do czytania symboli przed zmienną. Są bardziej przyciągające wzrok. Więc będę analizować się =albo ==przed 123albo xi skończyć nawet nie zadając sobie trudu tłumaczyć kod do angielskiego w głowie.
Izkata,
Ponadto większość kompilatorów będzie ostrzegać, jeśli pojawi się odpowiedni monit, chyba że ktoś użyje dodatkowych nawiasów klamrowych, więc spróbuje rozwiązać problem bez problemu.
Deduplicator,
47

Szkodliwy? Nie. Działa tak czy inaczej.

Zła praktyka? W najlepszym razie dyskusyjne. To proste programowanie obronne.

Czy warto się przespać? Nie

Wonko przy zdrowych zmysłach
źródło
8
A kiedy go czytam, natychmiast rozumiem kod, który jest dla mnie najważniejszym powodem do dyskusji na temat stylu kodowania. Całkowicie się zgadzam, nie warto tracić snu.
Jeff Siver
17

To jest po prostu flaimbait.

Nie, to nie wyrządza więcej szkody niż pożytku. Prosty.

Więcej słów?

Argument kompilatora? Ehm, może, może - nie pokładaj zbytniej wiary w komplementa, aby cię ocalić od siebie.

„Nie należy zapominać” - dobrze duh - no oczywiście, że nie powinno tymczasem jestem zmęczony, byłem kodowania cały dzień musiałam korzystać z dwóch różnych języków, a czasem, po prostu czasami istota ludzka robię błąd.

Istota tego rodzaju zachowania polega na tym, że jest defensywny, nie ma go, ponieważ spodziewasz się popełnić więcej błędów niż masz ubezpieczenie, ponieważ spodziewasz się katastrofy ... ale jeśli zrobisz, to miło jest być chronionym.

Ciężkie do przeczytania? Narzekasz, że porządny programista powinien mieć == przewodowy (co czyni wszelkiego rodzaju złe założenia), ale że sam ten sam porządny programista nie może odczytać wartości 0 ==?

Nie szkodzi, ma potencjalne korzyści, głupie pytanie, pozwól innym to zrobić, jeśli chcą i idź dalej.

Murph
źródło
6
Myślę, że wartość 0 == jest nienaturalna dla tych, którzy studiowali algebrę przed studiowaniem programowania.
mojuba,
4
To nie o to chodzi - tak, masz rację, że nie czyta dobrze, ale równie wiele rzeczy, które my, jako programiści, piszemy, nie układają się tak jak język naturalny i zależy od tego, jak interpretujesz to, co widzisz
Murph
4
Brawo .. Nie wspominając już o tym, że ponieważ czyta się nienaturalnie, jesteś skłonny zwracać na to większą uwagę, w ten sposób wychwytując potencjalne błędy.
mocj
7
@mocj - Dlatego wszyscy powinniśmy kodować tak tępo, jak to możliwe, aby upewnić się, że osoby czytające nasz kod naprawdę muszą czytać nasz kod?
Kaz Dragon
6
@mocj - Doceniam to, ale twój argument był taki, że „zacinanie się mózgu” podczas czytania warunkowego Yoda jest dobrą rzeczą. Zadaję pytanie, czy w takim przypadku powinniśmy dążyć do napisania całego kodu, aby spowodować „zacinanie się mózgu”? Prawdziwe pytanie.
Kaz Dragon
11

Nie nazwałbym tego krzywdą, ale jest to wstrętne. Więc nie, nie powiedziałbym, że tak.

Jaka jest nazwa?
źródło
10

Nigdy nie czułem, że całe „a jeśli zapomnę = =?” kiedykolwiek naprawdę miał dużą wagę. Tak, możesz zrobić literówkę, ale wszyscy robimy literówki, głupotą wydaje się zmiana całego stylu kodowania, ponieważ boisz się popełnić błąd. Dlaczego nie sprawić, by wszystkie zmienne i funkcje były pisane małymi literami bez żadnych znaków interpunkcyjnych, ponieważ możesz zapomnieć o pisaniu wielkich liter lub zapomnieć o podkreśleniu?

GSto
źródło
5
Nie o to chodzi w pytaniu, chodzi o to, czy to jest szkodliwe - i nie jest. W najgorszym przypadku bardzo niewielkie podrażnienie, ale nie jest szkodliwe.
Murph,
1
W dynamicznych językach - absolutnie możesz pomylić symbol i tracić czas na szukanie źródła błędu
mojuba,
3
z całym szacunkiem, kiedy spędzisz późną noc (lub dwie) i znajdziesz źródło (w kodzie C ++) to = zamiast ==, to będzie miało pewną wagę.
DevSolo,
2
@DevSolo: Myślę, że tak naprawdę powinno zdarzyć się raz lub dwa w twojej karierze, ale nie więcej niż
mojuba,
9

Niektórzy używają go, aby wyjaśnić dokładnie, co robi warunek. Na przykład:

Sposób 1:

FILE *fp;

fp = fopen("foo.txt", "w+");
if (fp == NULL) {

Sposób 2:

FILE *fp;

if (NULL == (fp = fopen("foo.txt", "w+"))) {

Niektórzy uważają, że drugi przykład jest bardziej zwięzły, lub odwrócenie argumentów ilustruje sens testu (warunkowy) przed samym testem.

W rzeczywistości tak naprawdę nie mam nic przeciwko. Mam swoje zwierzaki na punkcie stylu, a największym jest niekonsekwencja. Więc rób to w ten sam sposób, konsekwentnie i nie będę miał nic przeciwko czytaniu twojego kodu.

Wymieszaj to do momentu, w którym wygląda na to, że sześć różnych osób z własnym charakterystycznym stylem pracowało nad tym naraz, jestem trochę zirytowany.

Tim Post
źródło
4
Drugi przykład kazał mi powiedzieć „co?” Pierwszy jest znacznie bardziej czytelny. Świetny przykład. :)
Mateen Ulhaq
6

Dla mnie to proste warunkowanie. Jako ktoś, kto nauczył się (w latach 90.) C i C ++, przyzwyczaiłem się do niego i nadal go używam, pomimo tego, że przyczyny są lekcji.

Kiedy jesteś „uwarunkowany”, aby spojrzeć na „stałą” po lewej stronie, staje się on drugą naturą.

Używam go również tylko do równoważności (lub równoważności zanegowanej), a nie do większej / mniejszej niż.

Całkowicie zgadzam się z odpowiedzią W / @ Wonko.

DevSolo
źródło
5

Jedynym przypadkiem, w którym uważam to za pomocne, jest to, że zmienna część if jest dość długa, a zobaczenie wartości ułatwia odczytanie kodu. Języki kropkowane w przestrzeni nazw mają najlepsze tego przykłady.

Na przykład coś, nad czym pracowałem przy jednokrotnym logowaniu, miało sytuację, w której mogłeś mieć dwie równoczesne sesje, jeśli wystąpiłby pewien rodzaj błędu i został odzyskany w określony sposób, więc muszę dodać moduł obsługi tego, który był w środku i jeśli wyglądał coś takiego:

if (2 <= application.httpcontext.current.session["thenameofmysessiontoken"].items.count())

Wprawdzie w tym przykładzie istnieją inne sposoby, aby to zrobić, ale byłby to przypadek, w którym pierwsza wersja jest potencjalnie bardziej czytelna.

Rachunek
źródło
2
Myślę, że słowem kluczowym jest „inne sposoby, aby to zrobić”;)
mojuba,
w tym przypadku tak, ale w niektórych przypadkach jest to nadal najbardziej czytelny wynik. Chodzi mi tylko o to, że istnieją inne uzasadnione powody, by to zrobić inaczej niż walka z zachowaniem się języka lub ideów i typ-o
Bill
Szczerze mówiąc, mam trudności z warunkami Yoda dla <= i> =. Znak == to inna sprawa, ponieważ w mojej głowie mogę po prostu przełączać symbole, ale w twoim przypadku muszę pamiętać, że count () musi być większy lub równy 2, a to dość denerwujące znak mniejszej lub równej.
Alex
3

A jednak występują błędy. A czasem potrzebujesz przypisania w operatorze pętli, w którym możesz w przeciwnym razie sprawdzić równość, a przynajmniej standardową praktyką jest korzystanie z niego.

Trochę się z tym zgadzam. Porada, której podążyłem (prawdopodobnie z Code Complete), to zachować w porównaniach to, co powinno mieć niższą wartość po lewej stronie. Rozmawiałem o tym wcześniej z kolegą i pomyślał, że to trochę szalone, ale bardzo się do tego przyzwyczaiłem.

Powiedziałbym więc:

if ( 0 <= value )

Ale powiedziałbym również:

if ( value <= 100 )

Równość, którą zwykle sprawdzam za pomocą zmiennej po lewej, jest po prostu bardziej czytelna.

glenatron
źródło
1
Jestem przyzwyczajony do korzystania przez if(y > x)cały czas. Chyba że yjest stały.
Mateen Ulhaq,
Robiłem to w ten sposób, ale kiedy wpadłem na pomysł, aby po lewej stronie znaleźć najniższe wartości, mój kod jest znacznie bardziej czytelny na pierwszy rzut oka.
glenatron,