is.object 和 S3 类系统

csg*_*pie 5 oop r r-s3 r-s4

使用该class函数可以让我们确定一个对象的类:

> x = 5
> class(x)
[1] "numeric"
Run Code Online (Sandbox Code Playgroud)

我也明白我们可以使用is.object命令来确定一个对象是否有一个类。然而,一些对象类型是隐式的,即

> is.object(x)
[1] FALSE
Run Code Online (Sandbox Code Playgroud)

声明 R 中的所有变量都是对象并且is.object仅是对非隐式类的测试是否正确?

另外,类型如何适应这个。天真地,我认为以下代码会产生错误:

> x = 5
> class(x) = "fake"
> x = X + 1
> x + 1
[1] 6
attr(,"class")
[1] "fake"
Run Code Online (Sandbox Code Playgroud)

x仍然有“double”类型,一切仍然有效。可以将类型视为所有其他对象都继承自的超类吗?

Vit*_*hKa 3

typeof返回内部 C 表示的类型,并且它不用于方法分派。因此严格来说,您不能将类型视为“超类”。

相反,有一些基本类(数字、字符、列表、函数等)大致对应于 所返回的名称typeof,但并非总是如此(例如 double 类型属于 numeric 类,special 和closure 属于 function 类,而 data.frame 类)是列表类型!)。

使用 S3 和 S4 系统,您可以使用基本类构建重要的类(但不必扩展其中之一!!例如:setClass("foo", list(a="numeric",b="character")不扩展任何基本类)。

is.object对于从这些基本类返回的对象FALSE。正如其文档所述,此函数提供了一种非常快速的方法来检查对象是否属于用户构建的 S3 或 S4 类(即不是基本类之一)。

转换为x“假”后,您的对象正式不属于“数字”类:

is(x, "numeric")
#FALSE
Run Code Online (Sandbox Code Playgroud)

但它可以解释为基本的“数字”对象:

is.numeric(x)
#TRUE
Run Code Online (Sandbox Code Playgroud)

这就是+在这里工作的原因。因此,在内部,正如 @Richie 已经说过的,默认方法解释x为数字基本类。

这种概念上的混乱是由于 S3 对类的非正式处理造成的。请改用 S4。


typeof(.) 和 basic class(.) 的对应关系:

                              typeof(.)  class(.)
NULL                          "NULL"     "NULL"
1                             "double"   "numeric"
1:1                           "integer"  "integer"
1i                            "complex"  "complex"
list(1)                       "list"     "list"
data.frame(x=1)               "list"     "data.frame"
pairlist(pi)                  "pairlist" "pairlist"
c                             "special"  "function"
lm                            "closure"  "function"
formals(lm)[[1]]              "symbol"   "name"
formals(lm)[[2]]              "symbol"   "name"
y~x                           "language" "formula"
expression((1))[[1]]          "language" "("
(y~x)[[1]]                    "symbol"   "name"
expression(x <- pi)[[1]][[1]] "symbol"   "name"
Run Code Online (Sandbox Code Playgroud)