Angenommen, Sie haben eine C-Sprache ohne verwendet &&
und mussten den entsprechenden Code wie in Ihrer Frage ausführen.
Ihr Code wäre:
if(smartphone != null)
{
if(smartphone.GetSignal() > 50)
{
// Do stuff
}
}
Dieses Muster würde viel auftauchen.
Stellen Sie sich nun die Version 2.0 unserer hypothetischen Sprache vor &&
. Denken Sie, wie cool Sie denken würden, dass es war!
&&
ist das anerkannte, idiomatische Mittel, um das zu tun, was mein Beispiel oben tut. Es ist keine schlechte Praxis, es zu verwenden, in der Tat ist es eine schlechte Praxis, es in Fällen wie den oben genannten nicht zu verwenden: Ein erfahrener Programmierer in einer solchen Sprache würde sich fragen, wo der else
Grund dafür war, Dinge nicht auf die normale Art und Weise zu tun.
Die Sprache ist klug, weil sie weiß, dass es keinen Sinn macht, die zweite Anweisung zu bewerten, wenn die erste Anweisung falsch ist, und daher wird niemals eine Nullreferenzausnahme ausgelöst.
Nein, Sie sind schlau, denn Sie wussten, dass es keinen Sinn macht, die zweite Aussage zu bewerten, wenn die erste Aussage falsch ist. Die Sprache ist dumm wie eine Schachtel Steine und hat das getan, was Sie ihm gesagt haben. (John McCarthy war noch schlauer und erkannte, dass eine Kurzschlussbewertung eine nützliche Sache für Sprachen sein würde).
Der Unterschied zwischen Ihnen und der Sprache ist wichtig, da gute und schlechte Praxis oft darauf zurückzuführen ist, dass Sie so schlau wie nötig sind, aber nicht schlauer.
Erwägen:
if(smartphone != null && smartphone.GetSignal() > ((range = (range != null ? range : GetRange()) != null && range.Valid ? range.MinSignal : 50)
Dies erweitert Ihren Code, um a zu überprüfen range
. Wenn das range
null ist, versucht es, es durch einen Aufruf auf zu setzen, GetRange()
obwohl dies möglicherweise fehlschlägt und daher range
möglicherweise immer noch null ist. Wenn range danach nicht null ist und es Valid
dann seine MinSignal
Eigenschaft ist, wird andernfalls ein Standardwert von 50
verwendet.
Dies hängt &&
auch davon ab, aber es ist wahrscheinlich zu klug, es in eine Zeile zu setzen (ich bin nicht zu 100% sicher, dass ich es richtig gemacht habe, und ich werde es nicht noch einmal überprüfen, weil diese Tatsache meinen Standpunkt zeigt).
Das &&
ist hier jedoch nicht das Problem, aber die Fähigkeit, damit viel in einen Ausdruck zu schreiben (eine gute Sache), erhöht unsere Fähigkeit, schwer verständliche Ausdrücke unnötig zu schreiben (eine schlechte Sache).
Ebenfalls:
if(smartphone != null && (smartphone.GetSignal() == 2 || smartphone.GetSignal() == 5 || smartphone.GetSignal() == 8 || smartPhone.GetSignal() == 34))
{
// do something
}
Hier verbinde ich die Verwendung von &&
mit einer Prüfung auf bestimmte Werte. Dies ist bei Telefonsignalen nicht realistisch, kommt aber in anderen Fällen vor. Hier ist es ein Beispiel dafür, dass ich nicht schlau genug bin. Wenn ich folgendes getan hätte:
if(smartphone != null)
{
switch (smartphone.GetSignal())
{
case 2: case 5: case 8: case 34:
// Do something
break;
}
}
Ich hätte sowohl an Lesbarkeit als auch an Leistung gewonnen (die Mehrfachaufrufe GetSignal()
wären wahrscheinlich nicht wegoptimiert worden).
Auch hier ist das Problem nicht so sehr, &&
als diesen bestimmten Hammer zu nehmen und alles andere als Nagel zu sehen. Wenn ich es nicht benutze, kann ich etwas Besseres tun als wenn ich es benutze.
Ein letzter Fall, der von der bewährten Praxis abweicht, ist:
if(a && b)
{
//do something
}
Verglichen mit:
if(a & b)
{
//do something
}
Das klassische Argument, warum wir das letztere bevorzugen könnten, ist, dass es einige Nebeneffekte bei der Beurteilung gibt b
, ob wir wollen, ob a
es wahr ist oder nicht. Da bin ich anderer Meinung: Wenn dieser Nebeneffekt so wichtig ist, lassen Sie ihn in einer separaten Codezeile passieren.
In Bezug auf die Effizienz dürfte jedoch eine der beiden Möglichkeiten besser sein. Der erste führt offensichtlich weniger Code aus (überhaupt keine Bewertung b
in einem Codepfad), was uns die Zeit ersparen kann, die für die Bewertung erforderlich ist b
.
Der erste hat aber noch einen Zweig. Überlegen Sie, ob wir es in unserer hypothetischen C-Sprache mit no neu schreiben &&
:
if(a)
{
if(b)
{
// Do something
}
}
Dieses Extra if
ist in unserer Verwendung von versteckt &&
, aber es ist immer noch da. Als solcher ist es ein Fall, in dem eine Verzweigungsvorhersage stattfindet und daher möglicherweise eine Verzweigungsfehlvorhersage erfolgt.
Aus diesem Grund kann der if(a & b)
Code in einigen Fällen effizienter sein.
Hier würde ich sagen, dass dies zunächst if(a && b)
immer noch die beste Vorgehensweise ist: Häufiger, in einigen Fällen die einzige, die durchführbar ist (wo b
Fehler auftreten, wenn sie a
falsch ist) und häufiger als nicht. Es ist jedoch erwähnenswert, dass if(a & b)
dies in bestimmten Fällen häufig eine nützliche Optimierung darstellt.