is.object 和 S3 类系统
使用class
函数可以让我们确定一个对象的类:
> x = 5
> class(x)
[1] "numeric"
我也理解我们可以使用is.object
命令来确定一个对象是否有一个类。然而,有些对象类型是隐式的,也就是说
> is.object(x)
[1] FALSE
,声明 R 中的所有变量都是对象并且 is.object 仅对非隐式类进行测试是否正确?
另外,类型如何适应这一点。天真地,我认为下面的代码会产生错误:
> x = 5
> class(x) = "fake"
> x = X + 1
> x + 1
[1] 6
attr(,"class")
[1] "fake"
但是 x
仍然具有类型“double”,仍然一切仍然有效。类型可以被认为是所有其他对象继承自的超类吗?
Using the class
function allows us to determine the class of an object:
> x = 5
> class(x)
[1] "numeric"
I also understand that we can use the is.object
command to determine if an object has a class. However some object types are implicit, that is
> is.object(x)
[1] FALSE
Would it be correct to state that all variables in R are objects and is.object
is a test for non-implicit classes only?
Also, how do types fit into this. Naively, I thought that the following piece of code would produce an error:
> x = 5
> class(x) = "fake"
> x = X + 1
> x + 1
[1] 6
attr(,"class")
[1] "fake"
But x
still has type "double", still everything still works. Can types be thought of as a superclass that all other objects inherit from?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
typeof
返回内部 C 表示的类型,它不用于方法分派。因此严格来说,您不能将类型视为“超类”。相反,有基本类(数字、字符、列表、函数等),它们大致对应于名称
由
typeof
返回,但并非总是如此(例如 double 类型属于 numeric 类,special 和closure 属于此类函数,并且类 data.frame 是列表类型!)。
使用 S3 和 S4 系统,您可以使用基本类构建非平凡的类(但不必扩展其中之一!示例:
setClass("foo", list(a="numeric",b="character")< /code> 不扩展任何基本类)。
对于来自这些基本类的对象,
is.object
返回FALSE
正如其文档所述。 ,这个函数提供了一种非常快速的方法来检查对象是否属于用户构建的 S3 或 S4 类(即不是基本类之一)。
将
x
转换为“假”后,您的对象正式不属于“数字”类:但它可以解释为基本“数字”对象:
这就是
+
在这里工作的原因。因此,在内部,正如 @Richie 所说,默认方法将x
解释为数字基础类。
这种概念上的混乱是由于 S3 对类的非正式处理造成的。请改用 S4。
typeof(.) 和 basic class(.) 的对应关系:
typeof
returns the type of internal C representation, and it is not used for method dispatch. So strictly speaking you can not think of types as "superclasses".There are instead basic classes (numeric, character, list, function etc) which roughly correspond to the names
returned by
typeof
, but not always (for example type double is of class numeric, special and closure are of classfunction, and class data.frame is of type list!).
With S3 and S4 systems you can build non trivial classes using basic classes (but not necessary extending one of those!! example:
setClass("foo", list(a="numeric",b="character")
does not extend any of the basic classes).For objects from these basic classes
is.object
returnsFALSE
. As its documentation says, this function providesa very fast way to check if the object is of user build S3 or S4 class (i.e. not one of basic classes).
After casting
x
as "fake" your object is formally not of "numeric" class:but it is interpretable as basic "numeric" object:
And this is why
+
works here. So, internally, as @Richie already said the default method interpretsx
as ofnumeric basic class.
This conceptual mess is because of S3 informal treatment of classes. Use S4 instead.
correspondence between typeof(.) and basic class(.):
第一个问题的部分答案可以在 R 语言定义的第二章中找到
所以,是的,所有变量都是对象。
is.object
似乎或多或少相当于function(x) !is.null(attr(x, "class"))
但我愿意事实证明这一点是错误的。至于第二个问题,我认为是这样的:
由于
x
有类“fake”,R在加法中寻找方法+.fake
,但当找不到时,它会求助于默认方法。该默认方法基于底层 C 代码,它使用 typeof(x) (或 C 等效项)来确定应该做什么。在这种情况下,x
的类型是“整数”。A partial answer to the first question is found in Chapter 2 of the R language defninition
So, yes, all variables are objects.
is.object
seems to be more or less equivalent tofunction(x) !is.null(attr(x, "class"))
but I'm willing to be proved wrong on that.As for the second question, I think this is what happens:
Since
x
has class "fake", R looks for a method+.fake
in the addition but when it doesn't find one, it resorts to the default method. That default method is based upon underlying C code, which usestypeof(x)
(or a C equivalent) to determine what should be done. In this case the type ofx
is "integer".