Was ist der Unterschied zwischen „zu“ und „als“ Methode Namenspräfixe wie
- auflisten(),
- asList (),
- usw...
Wann welche beim Entwerfen einer Methode verwenden?
Was ist der Unterschied zwischen „zu“ und „als“ Methode Namenspräfixe wie
Wann welche beim Entwerfen einer Methode verwenden?
Antworten:
Von einer toXYZ()
Funktion wird erwartet, dass sie eine Konvertierung durchführt und ein neues unabhängiges Objekt java.lang.String.toString()
zurückgibt (obwohl die Unveränderlichkeit eine Optimierung ermöglicht, gibt sie nur das Objekt zurück).
Als Beispiel haben wir in C ++ ein Programm, std::bitset::to_ulong()
das leicht versagen kann, und eine ganze Fülle von Funktionen to_string()
, die eine (mehr oder weniger) komplexe Konvertierung durchführen und Speicher zuweisen.
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 gerade eine konstante Referenz zurückgibt, und das kompliziertere, std::forward_as_tuple
das auch auf seine Argumente durch Referenz verweist.
std::to_string(x)
ein neues Zeichenfolgenobjekt, std::as_const(x)
erstellt jedoch eine Referenz (eine Ansicht) des vorhandenen Objekts.
Ehrlich gesagt kann es nur Inkonsistenz benennen. Wenn Blick auf Standard - Bibliotheksobjekte in Smalltalk, zum Beispiel, alle Methoden , die „komplexe Konvertierungen“ oder „Rückkehr einfache Darstellungen in einer anderen Art“ sind mit dem Präfix tun as
, wie in asString
, asFloat
, asSeconds
, und die Standard - Methode für etwas auf etwas anderen Umwandlung as: aClass
.
In Ruby werden die gleichen Arten von Verfahren mit dem Präfix to_
, wie in to_s
, to_a
, to_h
, kurz für string
, array
und hash
jeweils.
Keine der Standardbibliotheken scheint zwischen verschiedenen Arten von Konvertierungen zu unterscheiden, wahrscheinlich, weil dies als Implementierungsdetail angesehen werden sollte.
In Java gibt es jedoch viele Verwechslungen. Wie Sie erwähnt haben , ist es toString
, asList
und so weiter. Ich glaube, dass dies nur eine Namensinkonsistenz ist, 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 ist es für Sie und Ihr Team wichtig, ein Präfix auszuwählen und es im gesamten Code einheitlich zu verwenden. Konsistenz ist der Schlüssel, damit sich die Menschen nicht wundern müssen, wie Sie es mussten.
toString
eine neue Zeichenfolge, die vollständig vom Objekt getrennt ist (und aufgrund der Unveränderlichkeit gibt es keine andere Möglichkeit). Das gleiche gilt zB für Collection#toArray
, während Arrays#asList
eine Ansicht des Arrays zurückgegeben wird, das bidirektional verbunden ist (das Mutieren des Arrays ändert die Liste und umgekehrt). Es ist also ziemlich konsistent, obwohl es Ausnahmen geben kann. Ein Präfix zu wählen wäre falsch. Wenn ja Arrays#toList
, würde ich erwarten, dass eine neue Liste mit einem neuen zugrunde liegenden Array erstellt wird.
Während es bereits eine akzeptierte Antwort gibt, scheint sie sich auf C ++ zu konzentrieren, während die Frage mit Java markiert ist . In Java ist Arrays.asList das erste Beispiel, das für diese Art von Dingen in den Sinn kommt. Es gibt im Wesentlichen eine Ansicht eines Arrays zurück, 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 Methode toArray 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 weiterhin in der Dokumentation nachsehen, ob dies das Verhalten ist, das Sie von unbekanntem Code erhalten.
Die andere Stelle, die ich als ... () - Methoden angesehen habe, ist das Downcasting von Typen zu Untertypen. Wenn Sie beispielsweise eine Reihe von Untertypen aufgelistet haben, erhalten Sie möglicherweise folgenden Code:
/**
* 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();
}
}
}
Der Unterschied, den ich bemerkte (gerade als ich darüber nachdachte), ist
Wir sehen also AsInteger und AsString und wir sehen ToArray und ToStringList.
Konversion implizieren, was Sinn macht (es ist eine Bewegung, ein Prozess). Wie impliziert eine Darstellung, eine Art, das ursprüngliche Objekt auszudrücken.
Eine andere Betrachtungsweise:
Und dann gibt es "Stand der Technik" (oder Vermächtnis), mit dem man sich befassen muss. Bevor Sprachen von Grund auf OO waren, gab es Bibliotheksfunktionen wie StrToInt () und IntToStr (). Sie führten Konvertierungen durch, es waren Operationen, daher machte es Sinn, sie SomethingToSomethingelse () zu nennen. Immerhin ist To aktiver als As. Ich denke hier besonders an Delphi.
Bei der Entwicklung von C # mit dem Ehrgeiz, stets OO zu verwenden, war es sinnvoll, eine Methode für das Objekt now integer zu verwenden, mit der die Ganzzahl in eine Zeichenfolge konvertiert wird. Obwohl wir auch eine Convert-Klasse haben, ist die Konvertierung in einen String so verbreitet, dass sie zu einer virtuellen Methode für ein Objekt gemacht wurde. Die Designer haben vielleicht gedacht, dass ToString den Leuten aus dem alten Paradigma vertrauter ist, und vielleicht haben wir deshalb eine virtuelle Methode ToString () und keine virtuelle Eigenschaft AsString.
toString()
?