it-swarm.com.de

Boolesche Rückgabe von set.add () in wenn bedingt?

Der Add-Operator der set-Klasse gibt einen Booleschen Wert zurück, der true ist, wenn das Element (das hinzugefügt werden soll) noch nicht vorhanden war, andernfalls false. Schreibt

if (set.add(entry)) {
    //do some more stuff
}

als guter Stil in Bezug auf das Schreiben von sauberem Code? Ich frage mich, da Sie zwei Dinge gleichzeitig tun. 1) Hinzufügen des Elements und 2) Überprüfen, ob das Element vorhanden ist.

15
Andreas Braun

Ja, so ist es.

Der übliche Punkt, an dem eine Operation einen Booleschen Wert zurückgibt, besteht darin, dass Sie damit Entscheidungen treffen können, d. H. Innerhalb eines if -Konstrukts. Die einzige andere Möglichkeit, dieses Potenzial zu realisieren, besteht darin, den Rückgabewert in einer Variablen zu speichern und ihn dann sofort in einem if wiederzuverwenden, was einfach albern ist und dem Schreiben von if(operation()) { ... }. Also mach einfach weiter und mach das, wir werden dich nicht beurteilen (dafür).

19
Kilian Foth

Ich würde sagen, es ist nicht so sauber wie möglich, weil es den Betreuer zwingt, entweder bereits zu wissen oder nachzuschlagen, was der Rückgabewert bedeutet. Bedeutet dies, dass der Wert bereits vorhanden war, noch nicht vorhanden war und erfolgreich eingefügt wurde? Wenn Sie es nicht oft benutzen, werden Sie es nicht wissen, und selbst wenn Sie es tun, ist es so viel mehr mentale Belastung.

Ich würde folgendes bevorzugen:

boolean added = set.add(entry);

if (added) {
    //do some more stuff
}

Ja, ein bisschen ausführlicher, aber der Compiler sollte ziemlich genau den gleichen Bytecode generieren, und selbst Leute, die seit Jahren nicht mehr Java Sets) verwendet haben, können der Logik folgen, ohne etwas nachzuschlagen.

12
Karl Bielefeldt

Wenn wahr Erfolg bedeutet, dann ist es guter, klarer Code.

Es gibt eine weit verbreitete Konvention, dass eine Funktion oder Methode beim Erfolg true zurückgibt (oder etwas, das als true bewertet wird). Solange Ihr Code dem folgt, denke ich, dass es in Ordnung ist, die Methode in die Bedingung zu setzen.

Code wie dieser ist meiner Ansicht nach unnötig überladen:

boolean frobulate_succeeded = thing.frobulate();

if (frobulate_succeeded) {
    ...
}

Es fühlt sich an, als würdest du dich wiederholen.

Die Frage nach der Bedeutung des Rückgabewerts ist jedoch nicht eindeutig. Sie sagen "ein Boolescher Wert, der angibt, ob das hinzugefügte Element bereits vorhanden ist", was bedeuten könnte, dass true bedeutet, dass das Element vorhanden war (und add nicht aufgetreten ist). Wenn dies der Fall ist, würde ich das Rückgabeverhalten der Methode idealerweise konventioneller ändern. Wenn dies nicht möglich ist, würde ich eine zusätzliche Zwischenvariable hinzufügen, mit der Sie das Rückgabeergebnis in Ihrem Code eindeutig kennzeichnen können (wie von anderen vorgeschlagen).

8
user82096

Ich würde sagen, es ist sehr C-ähnlich. Die meiste Zeit würde ich es vorziehen, eine beschreibend benannte Variable für ein Mutationsergebnis zu haben und keine Mutation in einer if-Bedingung.

Ein Compiler entfernt diese Variable, wenn sie sofort wiederverwendet wird. Ein Mensch wird es leichter haben, die Quelle zu lesen. Für mich ist es wichtiger.

Sollte jemand die Bedingung erweitern müssen, indem er der if-Bedingung eine and/or -Klausel hinzufügt, kann es sein, dass er in bestimmten Fällen aufgrund eines Kurzschlusses .add() nicht aufruft Auswertung. Wenn ein Kurzschluss nicht ausdrücklich erwartet wird, kann dies zu einem Fehler führen.

2
9000

Ihr Code scheint zu brechen Command Query Separation . Dies wird im Clean Code Book und im Function Structure Video besprochen. Aus Sicht von Clean Code denke ich, dass dies kein guter Stil ist.

„Sauberer Code ist einfach und direkt. Sauberer Code liest sich wie gut geschriebene Prosa. Sauberer Code verdeckt niemals die Absicht des Designers, sondern ist voller klarer Abstraktionen und unkomplizierter Kontrolllinien.

- Grady Booch, Autor für objektorientierte Analyse und Design mit Anwendungen “

Für mich ist die Absicht Ihres Codes unklar. Wird if beide ausgeführt, wenn der Eintrag erfolgreich hinzugefügt wird, oder auch wenn er bereits vorhanden ist? Was gibt add() zurück? der Gegenstand? Der Fehlercode?