Zunächst ist length
keine typische generische Funktion, sondern eine " Interne generische Funktion ". Sie können dies anhand der Definition sehen:
Vergleichen Sie dies mit einer typischen generischen Funktion:
%Vor% length
ruft direkt in .Primitive
auf, das dann den Versand ausführen kann, wenn es den Aufruf selbst nicht verarbeitet; Der typische Ansatz ist der direkte Aufruf von UseMethod
, der nur den Versand abwickelt. Beachten Sie auch, dass es keine Funktion length.default
gibt, weil der Code im Aufruf .Primitive
dies tut:
Ich bin mir nicht sicher, ob es vollständig definiert ist, wenn ein internes generisches System nach benutzerdefinierten Methoden sucht und wenn es nur interne Methoden verwendet; Ich denke, die allgemeine Idee ist, dass für eine Benutzer / Paket definierte (effektiv, Nicht-Kern-) Klasse die bereitgestellten Methoden verwendet werden. Aber das Überschreiben für interne Klassen kann oder kann nicht funktionieren.
Zusätzlich (obwohl dies für diesen Fall nicht unbedingt relevant ist) ist die Dokumentation selbst für eine typische generische Methode nicht eindeutig, was passieren sollte, wenn die Klasse implizit abgeleitet und nicht als Attribut angegeben wird. Erstens, was class()
berichtet, ist eine Verschmelzung von Dingen. Auf der Hilfeseite class
:
Viele R-Objekte haben ein
class
-Attribut, einen Zeichenvektor, der die Namen der Klassen angibt, von denen das Objekt erbt . Wenn das Objekt kein Klassenattribut hat, hat es eine implizite Klasse,"matrix"
,"array"
oder das Ergebnis vonmode(x)
(außer dass Integervektoren die implizite Klasse"integer"
haben).
Also, obwohl class
dasselbe für f
und g
zurückgibt, sind sie nicht gleich.
Nun, hier wird es mehrdeutig. Der Methodenversand wird in (mindestens) 2 Orten besprochen: die Hilfeseite class
und die Hilfeseite UseMethod
. UseMethod
sagt:
Wenn eine Funktion, die
UseMethod("fun")
aufruft, auf ein Objekt mit dem Klassenattributc("first", "second")
angewendet wird, sucht das System nach einer Funktion namensfun.first
und wendet sie, falls sie gefunden wird, auf das Objekt an. Wenn keine solche Funktion gefunden wird, wird eine Funktion namensfun.second
versucht. Wenn kein Klassenname eine geeignete Funktion erzeugt, wird die Funktionfun.default
verwendet, falls sie existiert oder ein Fehler auftritt.
Während class
sagt:
Wenn eine generische Funktion fun auf ein Objekt mit dem Klassenattribut
c("first", "second")
angewendet wird, sucht das System nach einer Funktion namensfun.first
und wendet sie, falls sie gefunden wird, auf das Objekt an. Wenn keine solche Funktion gefunden wird, wird eine Funktion namensfun.second
versucht. Wenn kein Klassenname eine geeignete Funktion erzeugt, wird die Funktionfun.default
verwendet (wenn sie existiert). Wenn es kein Klassenattribut gibt, wird die implizite Klasse und dann die Standardmethode versucht.
Der wirkliche Unterschied ist im letzten Satz, dass die class
Seite das UseMethod
nicht hat. UseMethod
sagt nicht, was passiert, wenn es kein Attribut class
gibt; class
sagt, dass die implizite Klasse zum Versenden verwendet wird. Ihr Code scheint darauf hinzuweisen, dass das, was in class
dokumentiert ist, nicht korrekt ist, da length.function
für g
aufgerufen worden wäre.
Was wirklich beim Methodenversand passiert, wenn kein Klassenattribut vorhanden ist, wird wahrscheinlich eine Prüfung des Quellcodes erfordern, da die Dokumentation scheinbar nicht hilft.
Tags und Links r