Tut "wenn (0 == Wert) ..." nicht mehr Schaden als Nutzen? [geschlossen]


49

Dies ist eines der Dinge, die ich am meisten hasse, wenn ich es im Code eines anderen sehe. Ich weiß, was es bedeutet und warum manche Leute es so machen ("Was ist, wenn ich versehentlich stattdessen '=' setze?"). Für mich ist es so, als würde ein Kind die Treppe hinuntergehen und die Stufen laut zählen.

Wie auch immer, hier sind meine Argumente dagegen:

  • Es stört den natürlichen Ablauf des Lesens des Programmcodes. Wir Menschen sagen "wenn Wert Null ist" und nicht "wenn Null Wert ist".
  • Moderne Compiler warnen Sie, wenn Sie einen Auftrag in Ihrem Zustand haben oder wenn Ihr Zustand aus nur diesem Auftrag besteht, der ohnehin verdächtig aussieht
  • Sie sollten nicht vergessen, doppeltes '=' zu setzen, wenn Sie Werte vergleichen, wenn Sie ein Programmierer sind. Sie können auch vergessen, "!" beim Testen von Ungleichheit.

17
Ich interessiere mich auch nicht sehr dafür, aber es ist ziemlich weit unten auf meiner persönlichen Liste von Haustier-Ärmeln.
Adam Crossland

7
Und Programmierer vermissen manchmal das doppelte '='. Es ist ein leichter Fehler, der leicht zu übersehen ist.
4.

8
Wie ist das nicht konstruktiv oder keine echte Frage?
TheLQ

7
Dies ist geschlossen, also hier ist meine kurze Meinung: Wie können sich die Leute erinnern, zu schreiben, 0 == valueaber nicht daran erinnern, zu schreiben ==? Ich meine, verdammt, wenn du darüber nachdenkst, warum schreibst du es nicht gleich richtig?
Dr. Hannibal Lecter

3
@muntoo: Laut Compilern sind viele Dinge "korrekt", ich denke nicht, dass dies ein sehr guter Benchmark ist.
Dr. Hannibal Lecter

Antworten:


59

Ah ja, "Yoda conditionals" ("Wenn der Wert Null ist, führen Sie diesen Code aus, den Sie müssen!"). Ich weise immer jeden an, der behauptet, er sei "besser" bei Werkzeugen wie Flusen (1). Dieses spezielle Problem wurde seit den späten 70er Jahren gelöst. Die meisten modernen Sprachen kompilieren nicht einmal einen Ausdruck wie if(x = 10), da sie sich weigern, das Ergebnis der Zuordnung zu einem Booleschen Wert zu erzwingen.

Wie andere gesagt haben, ist es sicherlich kein Problem, aber es provoziert ein bisschen kognitive Dissonanz.


32
+1 für "Yoda-Bedingungen". Ich würde es tatsächlich so machen. :)
Bobby Tables

3
Während die Reihenfolge in Ordnung ist, lehne ich den Vergleich mit Null ab, anstatt den einfachen Booleschen Cast if(!value).
SF.

1
Sie betrachten also Zuweisungen innerhalb einer Bedingung als Fehler?

4
"Die meisten modernen Sprachen werden dies nicht einmal kompilieren." Das Problem tritt auf, wenn Sie eine Sprache verwenden, die das Ergebnis der Zuweisung zu einem Booleschen Wert stillschweigend erzwingt. Die beliebteste Sprache, die mir dazu einfällt, ist JavaScript. Aus diesem Grund verwende ich auch in Java immer Yoda-Bedingungen, damit ich nicht vergesse, dies zu tun, wenn ich Javascript schreibe. Ich wechsle oft genug zwischen den beiden, so dass es ein Problem sein kann (und war).
Sam Hasler

3
Kennt jemand einen Compiler, der nicht kompiliert if (0 == x)?
Kristopher Ives

56

Es ist abscheulich, weil es eine kleine, aber spürbare mentale Steuer auferlegt.

Die Leute lesen von links nach rechts in praktisch allen Programmiersprachen (und den meisten natürlichen Sprachen).

Wenn ich sehe 123 == x, ist die Art, wie ich es mental analysiere:

  • 123- Na und? unvollständige Info.
  • == - Nun, 123 ist 123, warum testen Sie es ...
  • x- Ok, das ist es, worüber wir uns Sorgen machen. Erst jetzt habe ich den Kontext.
  • Überdenken Sie noch einmal, 123warum x damit verglichen wird.

Wenn ich x == 123mentales Parsen sehe, ist das:

  • x- Bietet Kontext, ich weiß, worum es bei der Bedingung geht. Ich kann mich dafür entscheiden, den Rest zu ignorieren. Aufgrund des vorherigen Ablaufs habe ich eine gute Idee, warum und was kommen wird (und wundere mich, wenn es anders ist).
  • == - Ich dachte auch.
  • 123 - Jep.

Die Störung ist klein (in einem einfachen Beispiel), aber ich bemerke es immer .

Den Wert an die erste Stelle zu setzen, kann eine gute Idee sein, wenn Sie darauf aufmerksam machen möchten , z if (LAUNCH_NUKES == cmd). Normalerweise ist das nicht die Absicht.


5
Genau. In natürlichen Sprachen kommt die Konstante immer aus dem gleichen Grund an letzter Stelle: Wenn das Licht rot ist ...
Mojuba

2
@mojuba Stimmt, es ist fast universell. Seltsamerweise gibt es einige natürliche Sprachen, in denen das Objekt vor dem Subjekt steht (OVS / OSV-Reihenfolge), aber sie sind alle dunkel.
dbkk

1
Andererseits neigen einige von uns dazu, die Symbole vor der Variablen zu lesen. Sie sind auffälliger. Also analysiere ich =oder ==vorher 123oder xund mache mir am Ende nicht einmal die Mühe, den Code in meinem Kopf ins Englische zu übersetzen.
Izkata,

Außerdem warnen die meisten Compiler, wenn sie ordnungsgemäß dazu aufgefordert werden, es sei denn, man verwendet zusätzliche geschweifte Klammern, sodass versucht wird, ein Nicht-Problem zu lösen.
Deduplizierer

47

Schädlich? Nein, es funktioniert so oder so.

Schlechte Praxis? Bestenfalls fraglich. Es ist eine einfache defensive Programmierung.

Lohnt es sich, den Schlaf zu verlieren? Nein.


8
Und wenn ich es lese, verstehe ich sofort den Code, der für mich der wichtigste Grund ist, über einen Codierungsstil zu diskutieren. Ich stimme voll und ganz zu, es lohnt sich nicht, den Schlaf zu verlieren.
Jeff Siver

17

Dies ist im Grunde flaimbait.

Nein, es schadet nicht mehr als es nützt. Einfach.

Mehr Wörter?

Compiler-Argument? Ähm, ish, vielleicht - vertraue nicht zu sehr auf den Komplizen, um dich vor dir selbst zu retten.

"Du solltest nicht vergessen" - na ja - nein, natürlich solltest du nicht, dass ich müde bin. Ich habe den ganzen Tag lang programmiert. Ich musste zwei verschiedene Sprachen verwenden und manchmal, manchmal, bin ich ein Mensch ein Fehler.

Der Sinn dieser Art von Verhalten ist, dass es defensiv ist, es ist nicht da, weil Sie erwarten, Fehler zu machen, genauso wie Sie eine Versicherung haben, weil Sie einen Absturz erwarten ... aber wenn Sie es tun, ist es schön, gedeckt zu sein.

Schwer zu lesen? Sie beschweren sich, dass ein anständiger Programmierer == fest verdrahtet haben sollte (was alle möglichen schlechten Annahmen macht), aber dass derselbe anständige Programmierer den Wert 0 == nicht lesen kann?

Schadet nicht, hat potenzielle Vorteile, alberne Frage, lass es andere tun, wenn sie wollen und weiterziehen.


6
Ich denke, 0 == Wert liest sich unnatürlich für diejenigen, die Algebra studiert haben, bevor sie Programmierung studiert haben.
Mojuba

4
Das ist irgendwie nicht der Punkt - ja, Sie haben Recht, es liest sich nicht richtig, aber ebenso viel von dem, was wir als Programmierer schreiben, ist nicht gerade eine natürliche Sprache und es hängt davon ab, wie Sie was interpretieren Sie sehen
Murph

4
Bravo. Ganz zu schweigen von der Tatsache, dass Sie , weil es unnatürlich liest, dazu neigen, genauer darauf zu achten, um potenzielle Fehler zu finden.
4.

7
@mocj - Deshalb sollten wir alle so stumpf wie möglich codieren, um sicherzustellen, dass Menschen, die unseren Code lesen, unseren Code wirklich lesen müssen.
Kaz Dragon

6
@mocj - Ich weiß das zu schätzen, aber Ihr Argument war, dass das "Hirnstottern" beim Lesen der Yoda-Bedingung eine gute Sache ist. Ich stelle die Frage, ob wir in diesem Fall darauf abzielen sollten, den gesamten Code so zu schreiben, dass wir "Gehirnstottern" verursachen. Echte Frage.
Kaz Dragon

11

Ich würde es nicht als schädlich bezeichnen, aber es ist widerlich. Also nein, ich würde nicht sagen, dass es das tut.


10

Ich habe noch nie das Gefühl gehabt, dass das Ganze "was ist, wenn ich ein = vergesse?" jemals wirklich viel Gewicht gehalten. Ja, Sie können einen Tippfehler machen, aber wir alle machen Tippfehler. Es scheint dumm, Ihren gesamten Codierungsstil zu ändern, weil Sie Angst haben, einen Fehler zu machen. Warum nicht alle Variablen und Funktionen ohne Satzzeichen in Kleinbuchstaben schreiben, weil Sie eines Tages vergessen könnten, Groß- oder Kleinschreibung zu verwenden oder einen Unterstrich zu vergessen?


5
Das ist nicht der Punkt der Frage, der Punkt ist "ist es schädlich" - und das ist es nicht. Im schlimmsten Fall eine sehr geringe Reizung, aber nicht schädlich.
Murph

1
In dynamischen Sprachen - absolut können Sie ein Symbol falsch eingeben und Ihre Zeit damit verschwenden, später nach der Quelle Ihres Fehlers zu
suchen

3
Mit allem Respekt, wenn Sie eine Nacht (oder zwei) verbracht haben und festgestellt haben, dass die Quelle (in C ++) ein = anstelle von == ist, hat sie etwas Gewicht.
DevSolo

2
@ DevSolo: Ich denke, dass sollte wirklich ein oder zwei Mal in Ihrer Karriere passieren, aber nicht mehr als das
Mojuba

9

Einige Leute verwenden es, um genau zu verdeutlichen, was eine Bedingung tut. Zum Beispiel:

Weg 1:

FILE *fp;

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

Weg 2:

FILE *fp;

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

Einige Leute glauben, dass das zweite Beispiel prägnanter ist, oder dass das Umkehren von Argumenten den (bedingten) Sinn eines Tests vor dem eigentlichen Test verdeutlicht.

Eigentlich macht es mir auch nichts aus. Ich habe ein Faible für Stil und das größte Problem ist die Inkonsistenz. Tun Sie es also konsequent auf die gleiche Weise, und es macht mir nichts aus, Ihren Code zu lesen.

Mischen Sie es bis zu dem Punkt, an dem es aussieht, als ob sechs verschiedene Leute mit ihrem eigenen unverwechselbaren Stil gleichzeitig daran gearbeitet haben. Ich ärgere mich ein wenig.


4
Das zweite Beispiel veranlasste mich zu "huh?" Das erste ist viel lesbarer. Tolles Beispiel. :)
Mateen Ulhaq

6

Für mich ist es eine einfache Konditionierung. Als jemand, der (in den 90er Jahren) C und C ++ gelernt hat, habe ich mich daran gewöhnt und benutze es immer noch, auch wenn die Gründe nicht klar sind.

Sobald Sie "konditioniert" sind, um auf der linken Seite nach der "Konstante" zu suchen, wird dies zur zweiten Natur.

Ich benutze es auch nur für Äquivalenz (oder negierte Äquivalenz), nicht für größer / kleiner als.

Ich stimme voll und ganz der Antwort von Wonko zu.


5

Der einzige Fall, in dem ich es hilfreich finde, ist, dass der variable Teil des if ziemlich lang ist und das Anzeigen der Werte das Lesen des Codes erleichtert. Die gepunkteten Namespace-Sprachen haben die besten Beispiele dafür.

Zum Beispiel hatte etwas, an dem ich mit Single Sign-On gearbeitet habe, eine Situation, in der Sie zwei Sitzungen gleichzeitig abhalten konnten, wenn eine bestimmte Art von Fehler auftrat und auf eine bestimmte Weise behoben wurde etwas wie das:

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

Zwar gibt es in diesem Beispiel andere Möglichkeiten, dies zu tun, aber dies wäre ein Fall, in dem die Version mit der ersten Nummer möglicherweise besser lesbar ist.


2
Ich denke, das Schlüsselwort hier ist "andere Möglichkeiten, dies zu tun";)
Mojuba

in diesem Fall ja, aber in einigen Fällen ist dies immer noch das am besten lesbare Ergebnis. Mein einziger Punkt ist , gibt es einige legitimen Gründe , dies zu tun außer zu bekämpfen Sprache oder ide Verhalten und Typ-o
Bill

Um ehrlich zu sein, habe ich Schwierigkeiten mit den Yoda-Bedingungen für <= und> =. Das == -Zeichen ist eine andere Sache, weil ich in meinem Kopf nur die Symbole umschalten kann, aber in Ihrem Fall muss ich mich daran erinnern, dass count () größer oder gleich 2 sein muss, und das ist ziemlich ärgerlich, davon abzuleiten ein kleineres oder gleiches Zeichen.
Alex

3

Und doch treten die Fehler auf. Und manchmal möchten Sie eine Zuweisung in einem Schleifenoperator, in dem Sie sonst die Gleichheit überprüfen könnten, oder zumindest ist es üblich, sie zu verwenden.

Ich halte etwas daran fest. Der Rat, den ich befolgt habe (möglicherweise von Code Complete), ist, den niedrigeren Wert links im Vergleich beizubehalten. Ich habe das vorher mit einem Kollegen besprochen und er fand es irgendwie verrückt, aber ich habe mich sehr daran gewöhnt.

Also würde ich sagen:

if ( 0 <= value )

Ich würde aber auch sagen:

if ( value <= 100 )

Gleichheit Ich werde eher mit der Variablen auf der linken Seite nachsehen, sie ist nur lesbarer.


1
Ich bin es gewohnt, die if(y > x)ganze Zeit zu benutzen . Es ysei denn, ist eine Konstante.
Mateen Ulhaq

Früher habe ich das so gemacht, aber als ich auf die Idee kam, links die niedrigsten Werte zu haben, stellte ich fest, dass mein Code auf einen Blick viel besser lesbar ist.
Glenatron
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.