it-swarm.com.de

Was ist der Unterschied zwischen den Präfixen "to" und "as"?

Was ist der Unterschied zwischen "to" und "as" Methodennamenpräfixen wie

  • auflisten(),
  • asList (),
  • usw...

Wann welche beim Entwerfen einer Methode verwenden?

80
Daniel Hári

Von einer toXYZ() -Funktion wird erwartet, dass sie eine Konvertierung durchführt und ein neues unabhängiges Objekt zurückgibt (obwohl Unveränderlichkeit eine Optimierung ermöglicht, Java.lang.String.toString() gibt nur das Objekt zurück).
Als Beispiel haben wir in C++ std::bitset::to_ulong() , was leicht fehlschlagen kann, und eine ganze Fülle von to_string() , die alle a ausführen (mehr oder weniger) komplexe Konvertierung und Speicherzuweisung.

Von einer asXYZ() -Funktion wird hingegen erwartet, dass sie eine (möglicherweise andere) Ansicht der Quelle zurückgibt und nur minimale Arbeit leistet.
Als Beispiel haben wir in C++ std::as_const() , das nur eine konstante Referenz zurückgibt, und das involviertere std::forward_as_Tuple was auch auf seine Argumente durch Bezugnahme verweist.

120
Deduplicator

Ehrlich gesagt kann es nur sein, Inkonsistenz zu benennen. Wenn Sie sich beispielsweise Standardbibliotheksobjekte in Smalltalk ansehen, wird allen Methoden, die "komplexe Konvertierungen" durchführen oder "einfache Darstellungen in einem anderen Typ zurückgeben", as vorangestellt, wie in asString, asFloat, asSeconds und die Standardmethode zum Konvertieren von etwas in etwas anderes, as: aClass.

In Ruby wird to_ Den gleichen Methoden vorangestellt wie in to_s, to_a, to_h, Kurz für string, array bzw. hash.

Keine der Standardbibliotheken scheint zwischen verschiedenen Arten von Konvertierungen zu unterscheiden, wahrscheinlich weil dies als Implementierungsdetail betrachtet werden sollte.

In Java sehen wir jedoch viel Verwechslung. Wie Sie erwähnt haben, gibt es toString, asList und so weiter. Ich glaube, das sind gerecht Eine Namensinkonsistenz, denn wenn Sie versuchen, für jedes Präfix eine andere Bedeutung zu definieren, finden Sie immer ein Gegenbeispiel an einer anderen Stelle in der Standardbibliothek.

In jedem Fall würde ich sagen, dass es für Sie und Ihr Team wichtig ist, ein Präfix auszuwählen und es im gesamten Code konsistent zu verwenden. Konsistenz ist der Schlüssel, damit sich die Leute nicht wundern müssen, wie Sie es mussten.

13
MichelHenrich

Obwohl es bereits eine akzeptierte Antwort gibt, scheint sie sich auf C++ zu konzentrieren, während die Frage mit Java markiert ist. In Java ist das erste Beispiel, das für diese Art von Dingen in den Sinn kommt, Arrays.asList, das im Wesentlichen eine Ansicht eines Arrays zurückgibt, das in eine Liste eingeschlossen ist. Das zugrunde liegende Array und die Liste sind jedoch weiterhin verbunden. Änderungen am Array werden in der Liste angezeigt und umgekehrt. Das von der toArray -Methode der Liste zurückgegebene Array ist jedoch unabhängig vom ursprünglichen Array und von der Liste:

String[] wordArray = {"one", "fine", "day"};
List<String> wordList = Arrays.asList(wordArray);

// changes to the array are visible in the list
System.out.println(wordList); // prints "[one, fine, day]"
wordArray[1] = "horrible";
System.out.println(wordList); // prints "[one, horrible, day]"

// changes to the list are visible in the array
wordList.set(1, "beautiful");
System.out.println(wordArray[1]); // prints "beautiful"

// but changes to the list or array don't affect the 
// result from the list's toArray method.
String[] moreWords = wordList.toArray(new String[] {});
wordList.set(0, "the");
wordArray[1] = "best";
for (int i=0; i<3; i++) {
  System.out.println(moreWords[i]); // prints "one", "beautiful", and "day"
}

Trotzdem gibt es keine Garantie dafür, dass jeder Bibliotheksentwickler diese Konvention befolgt. Sie müssen daher immer noch die Dokumentation überprüfen, um herauszufinden, ob dies das Verhalten ist, das Sie von unbekanntem Code erhalten.

Der andere Ort, den ich gesehen habe als ... () häufig verwendete Methoden, ist das Downcasting von Typen in Untertypen. Wenn Sie beispielsweise eine Reihe von Untertypen aufgelistet haben, erhalten Sie möglicherweise Code wie:

  /**
   * Every Node is either an ANode or a BNode.
   */
  interface Node {

    /**
     * Returns this Node as an ANode.
     * 
     * @return this node
     */
    default ANode asANode() {
      if (this instanceof ANode) {
        return (ANode) this;
      }
      else {
        throw new UnsupportedOperationException();
      }
      // Or, in Java8 style, perhaps:
      // return Optional.of(this)
      //     .filter(ANode.class::isInstance)
      //     .map(ANode.class::cast)
      //     .orElseThrow(UnsupportedOperationException::new);
    }

    /**
     * Returns this Node as a BNode.
     * 
     * @return this node
     */
    default BNode asBNode() {
      if (this instanceof BNode) {
        return (BNode) this;
      }
      else {
        throw new UnsupportedOperationException();
      }
    }
  }
6
Joshua Taylor

Der Unterschied, den ich bemerkte (gerade jetzt, als ich darüber nachdachte), ist

  • Konvertiert normalerweise in einen anderen Referenztyp (ein etwas komplexes Objekt)
  • Gibt normalerweise einen einfachen Werttyp zurück

Wir sehen also AsInteger und AsString und wir sehen ToArray und ToStringList.

Eine Bekehrung implizieren, die Sinn macht (es ist eine Bewegung, ein Prozess). Wie impliziert eine Darstellung, eine Art, das ursprüngliche Objekt auszudrücken.

Eine andere Sichtweise:

  • To ist eine Operation, daher würden Sie sie für Methoden verwenden.
  • Da es sich um eine einfache Darstellung handelt, würden Sie sie für Eigenschaften verwenden.

Und dann gibt es "Stand der Technik" (oder Vermächtnis) zu behandeln. Bevor die Sprachen vollständig waren OO von Grund auf hatten Sie Bibliotheksfunktionen wie StrToInt () und IntToStr (). Sie führten Konvertierungen durch, es waren Operationen, daher war es sinnvoll, sie SomethingToSomethingelse () zu nennen. Immerhin ist To aktiver als As. Ich denke hier besonders an Delphi.

Als C # mit dem Ziel entworfen wurde, OO den ganzen Weg zu gehen), war es sinnvoll, eine Methode für das jetzt ganzzahlige Objekt zu haben, die die Ganzzahl in eine Zeichenfolge konvertiert. Obwohl wir auch eine Konvertierung haben Klasse, Konvertierung in Zeichenfolge ist so häufig, dass es sich um eine virtuelle Methode für ein Objekt handelt. Die Designer haben möglicherweise angenommen, dass ToString den Menschen aus dem alten Paradigma besser bekannt ist, und vielleicht haben wir deshalb eine virtuelle Methode ToString () und nicht eine virtuelle Eigenschaft AsString.

1
Martin Maat