Frage

Heute hat mir ein Kollege vorgeschlagen, meinen Code so umzugestalten, dass er eine Label-Anweisung verwendet, um den Fluss durch zwei verschachtelte for-Schleifen zu steuern, die ich erstellt hatte.Ich habe sie noch nie verwendet, weil ich persönlich der Meinung bin, dass sie die Lesbarkeit eines Programms beeinträchtigen.Ich bin jedoch bereit, meine Meinung über ihre Verwendung zu ändern, wenn das Argument stichhaltig genug ist.Welche Meinung haben die Leute zu Etikettenaussagen?

War es hilfreich?

Lösung

Viele Algorithmen lassen sich einfacher ausdrücken, wenn Sie über zwei Schleifen (oder eine Schleife mit einer switch-Anweisung) springen können.Habe kein schlechtes Gewissen deswegen.Andererseits kann es ein Hinweis auf eine zu komplexe Lösung sein.Treten Sie also zurück und schauen Sie sich das Problem an.

Manche Leute bevorzugen den Ansatz „Einzeleingang, Einzelausgang“ für alle Schleifen.Das bedeutet, dass Unterbrechungen (und Fortsetzungen) und vorzeitige Rückkehr für Schleifen insgesamt vermieden werden.Dies kann zu doppeltem Code führen.

Was ich strikt vermeiden würde, ist die Einführung von Hilfsvariablen.Das Verbergen des Kontrollflusses innerhalb des Staates trägt zur Verwirrung bei.

Die Aufteilung beschrifteter Schleifen in zwei Methoden kann durchaus schwierig sein.Ausnahmen sind wahrscheinlich zu schwergewichtig.Versuchen Sie es mit einem Single-Entry-Single-Exit-Ansatz.

Andere Tipps

Beschriftungen sind wie Gotos:Verwenden Sie sie sparsam und nur, wenn sie Ihren Code schneller machen Und noch wichtiger, verständlicher,

Wenn Sie sich beispielsweise in großen Schleifen mit einer Tiefe von sechs Ebenen befinden und auf eine Bedingung stoßen, die den Abschluss des Rests der Schleife sinnlos macht, macht es keinen Sinn, in Ihren Bedingungsanweisungen sechs zusätzliche Falltüren einzubauen, um die Schleife vorzeitig zu verlassen.

Beschriftungen (und Gotos) sind nicht böse, es ist nur so, dass Menschen sie manchmal auf schlechte Weise verwenden.Meistens versuchen wir tatsächlich, unseren Code so zu schreiben, dass er für Sie und den nächsten Programmierer, der vorbeikommt, verständlich ist.Es ist zweitrangig, es extrem schnell zu machen (Vorsicht vor vorzeitiger Optimierung).

Wenn Labels (und Gotos) missbraucht werden, wird der Code schlechter lesbar, was Ihnen und dem nächsten Entwickler Ärger bereitet.Dem Compiler ist es egal.

Es gibt nur wenige Gelegenheiten, in denen Sie Etiketten benötigen, und diese können verwirrend sein, da sie selten verwendet werden.Wenn Sie jedoch eines benötigen, dann verwenden Sie eines.

Übrigens:Dies wird kompiliert und ausgeführt.

class MyFirstJavaProg {  
        public static void main(String args[]) {
           http://www.javacoffeebreak.com/java101/java101.html
           System.out.println("Hello World!");
        }
}

Ich bin gespannt, was Ihre Alternative zu Etiketten ist.Ich denke, das wird im Wesentlichen auf das Argument „so früh wie möglich zurückkehren“ vs. „Rückkehr so ​​früh wie möglich“ hinauslaufen.„Verwenden Sie eine Variable, um den Rückgabewert zu speichern, und geben Sie erst am Ende zurück.“

Beschriftungen sind ziemlich Standard, wenn Sie verschachtelte Schleifen haben.Sie beeinträchtigen die Lesbarkeit nur dann wirklich, wenn ein anderer Entwickler sie noch nie zuvor gesehen hat und nicht versteht, was sie bedeuten.

Ich habe noch nie Labels gesehen, die „in freier Wildbahn“ in Java-Code verwendet wurden.Wenn Sie verschachtelte Schleifen wirklich durchbrechen möchten, prüfen Sie, ob Sie Ihre Methode so umgestalten können, dass eine frühe Return-Anweisung das tut, was Sie wollen.

Technisch gesehen gibt es meiner Meinung nach keinen großen Unterschied zwischen einer vorzeitigen Rückkehr und einem Label.Praktisch jedoch hat fast jeder Java-Entwickler eine frühe Rückkehr gesehen und weiß, was es tut.Ich vermute, dass viele Entwickler von einer Bezeichnung zumindest überrascht und wahrscheinlich verwirrt wären.

In der Schule wurde mir die Single-Entry-/Single-Exit-Orthodoxie beigebracht, aber seitdem habe ich gelernt, frühe Return-Anweisungen und das Ausbrechen von Schleifen als eine Möglichkeit zu schätzen, den Code zu vereinfachen und klarer zu machen.

Ich würde sie an manchen Stellen befürworten, in diesem Beispiel fand ich sie besonders nützlich:


nextItem: for(CartItem item : user.getCart()) {

  nextCondition : for(PurchaseCondition cond : item.getConditions()) {
     if(!cond.check())
        continue nextItem;
     else
        continue nextCondition;

  }
  purchasedItems.add(item);
}

Ich denke, mit der neuen for-each-Schleife kann die Bezeichnung wirklich klar sein.

Zum Beispiel:

sentence: for(Sentence sentence: paragraph) {
  for(String word: sentence) {
    // do something
    if(isDone()) {
      continue sentence;
    }
  }
}

Ich denke, das sieht wirklich klar aus, wenn Ihre Bezeichnung mit Ihrer Variablen im neuen for-each übereinstimmt.Tatsächlich sollte Java vielleicht böse sein und implizite Beschriftungen für jede Variable hinzufügen, heh

Ich habe eine Java-Label-Schleife für eine Implementierung einer Sieve-Methode verwendet, um Primzahlen zu finden (durchgeführt für eines der Euler-Matheaufgaben des Projekts), was sie im Vergleich zu verschachtelten Schleifen zehnmal schneller machte.Wenn beispielsweise (bestimmte Bedingung) zur äußeren Schleife zurückgehe.

private static void testByFactoring() {
    primes: for (int ctr = 0; ctr < m_toFactor.length; ctr++) {
        int toTest = m_toFactor[ctr];
        for (int ctr2 = 0; ctr2 < m_divisors.length; ctr2++) {
            // max (int) Math.sqrt(m_numberToTest) + 1 iterations
            if (toTest != m_divisors[ctr2]
                        && toTest % m_divisors[ctr2] == 0) {
                continue primes; 
            }
        } // end of the divisor loop
    } // end of primes loop
} // method

Ich habe einen C++-Programmierer gefragt, wie schlecht beschriftete Schleifen sind. Er sagte, er würde sie sparsam verwenden, aber sie können gelegentlich nützlich sein.Wenn Sie beispielsweise drei verschachtelte Schleifen haben und unter bestimmten Bedingungen zur äußersten Schleife zurückkehren möchten.

Sie haben also ihren Nutzen, es hängt von dem Problem ab, das Sie lösen wollten.

Ich verwende in meinem Code niemals Labels.Ich bevorzuge es, einen Schutz zu erstellen und ihn zu initialisieren Null oder ein anderer ungewöhnlicher Wert.Dieser Schutz ist oft ein Ergebnisobjekt.Ich habe weder gesehen, dass einer meiner Kollegen Etiketten verwendet hat, noch habe ich welche in unserem Repository gefunden.Es hängt wirklich von Ihrem Codierungsstil ab.Meiner Meinung nach würde die Verwendung von Labels die Lesbarkeit beeinträchtigen, da es sich nicht um ein übliches Konstrukt handelt und normalerweise in Java nicht verwendet wird.

Ja, Sie sollten die Verwendung von Labels vermeiden, es sei denn, es gibt einen bestimmten Grund für deren Verwendung (das Beispiel dafür, dass es die Implementierung eines Algorithmus vereinfacht, ist relevant).In einem solchen Fall würde ich empfehlen, ausreichend Kommentare oder andere Dokumentation hinzuzufügen, um die Gründe dafür zu erläutern, damit später nicht jemand vorbeikommt und es aus der Vorstellung herausholt, „den Code zu verbessern“ oder „den Codegeruch loszuwerden“ oder Irgendeine andere, möglicherweise Quatsch-Ausrede.

Ich würde diese Art von Frage mit der Entscheidung gleichsetzen, wann man das ternäre Wenn verwenden sollte oder nicht.Der Hauptgrund dafür ist, dass es die Lesbarkeit beeinträchtigen kann. Wenn der Programmierer nicht sehr darauf achtet, die Dinge sinnvoll zu benennen, könnte die Verwendung von Konventionen wie Labels die Sache noch viel schlimmer machen.Angenommen, das Beispiel mit „nextCondition“ und „nextItem“ hätte „loop1“ und „loop2“ als Labelnamen verwendet.

Persönlich gehören Beschriftungen zu den Funktionen, die für mich außerhalb von Assembly oder BASIC und anderen ähnlich eingeschränkten Sprachen keinen großen Sinn ergeben.Java verfügt über viele konventionellere/regulärere Schleifen- und Kontrollkonstrukte.

Ich fand, dass Beschriftungen in Tests manchmal nützlich sind, um die üblichen Aufbau-, Übungs- und Überprüfungsphasen und gruppenbezogenen Aussagen zu trennen.Verwenden Sie beispielsweise die BDD-Terminologie:

@Test
public void should_Clear_Cached_Element() throws Exception {
    given: {
        elementStream = defaultStream();
        elementStream.readElement();
        Assume.assumeNotNull(elementStream.lastRead());
    }
    when:
        elementStream.clearLast();
    then:
        assertThat(elementStream.lastRead()).isEmpty();
}

Ihre Formatierungsoptionen können variieren, aber der Kerngedanke besteht darin, dass Beschriftungen in diesem Fall eine deutliche Unterscheidung zwischen den logischen Abschnitten Ihres Tests ermöglichen, und zwar besser als Kommentare.Ich denke der Spock Die Bibliothek baut einfach auf genau dieser Funktion auf, um ihre Testphasen zu deklarieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top