Class 个 <- R 中的调用
Class of <- calls in R
这可能是一个简单的问题。但是,为什么这两个 class 不同?
class(call("assign", "x", 2))
[1] "call"
class(call("<-", "x", 2))
[1] "<-"
为什么有 <-
class 来电?
我有理由确定这种行为是 S 的遗留问题,与 R 无关。您正在使用 R 语言中定义相对不明确的部分:什么是 class使用 S3 或 S4 的对象?
我们翻源码寻找答案:
class
#> function (x) .Primitive("class")
pryr::show_c_source(.Primitive("class"))
#> class is implemented by R_do_data_class with op = 0
这导致我们 R_do_data_class
and then R_data_class
. The object isn't S4, and doesn't have an class attribute, so it fails back to some defaults. In the case of LANGSXPs it calls lang2str
:
/* character elements corresponding to the syntactic types in the
grammar */
static SEXP lang2str(SEXP obj, SEXPTYPE t)
{
SEXP symb = CAR(obj);
static SEXP if_sym = 0, while_sym, for_sym, eq_sym, gets_sym,
lpar_sym, lbrace_sym, call_sym;
if(!if_sym) {
/* initialize: another place for a hash table */
if_sym = install("if");
while_sym = install("while");
for_sym = install("for");
eq_sym = install("=");
gets_sym = install("<-");
lpar_sym = install("(");
lbrace_sym = install("{");
call_sym = install("call");
}
if(isSymbol(symb)) {
if(symb == if_sym || symb == for_sym || symb == while_sym ||
symb == lpar_sym || symb == lbrace_sym ||
symb == eq_sym || symb == gets_sym)
return PRINTNAME(symb);
}
return PRINTNAME(call_sym);
}
你可以看到这个函数特例了一些函数调用它们自己的class。
我不认为这些 classes 当前在 R 源代码中使用,但您可以自己使用它们:
f <- function(x) UseMethod("f")
f.if <- function(x) "If statement"
f.while <- function(x) "While loop"
x <- quote(if (a) TRUE)
f(x)
#> "If statement"
y <- quote(while(TRUE){})
f(y)
#> "While loop"
(当然,实际这样做是个坏主意,因为这是该语言的一个极其深奥的角落,没有人会理解它是如何工作的)
这可能是一个简单的问题。但是,为什么这两个 class 不同?
class(call("assign", "x", 2))
[1] "call"
class(call("<-", "x", 2))
[1] "<-"
为什么有 <-
class 来电?
我有理由确定这种行为是 S 的遗留问题,与 R 无关。您正在使用 R 语言中定义相对不明确的部分:什么是 class使用 S3 或 S4 的对象?
我们翻源码寻找答案:
class
#> function (x) .Primitive("class")
pryr::show_c_source(.Primitive("class"))
#> class is implemented by R_do_data_class with op = 0
这导致我们 R_do_data_class
and then R_data_class
. The object isn't S4, and doesn't have an class attribute, so it fails back to some defaults. In the case of LANGSXPs it calls lang2str
:
/* character elements corresponding to the syntactic types in the
grammar */
static SEXP lang2str(SEXP obj, SEXPTYPE t)
{
SEXP symb = CAR(obj);
static SEXP if_sym = 0, while_sym, for_sym, eq_sym, gets_sym,
lpar_sym, lbrace_sym, call_sym;
if(!if_sym) {
/* initialize: another place for a hash table */
if_sym = install("if");
while_sym = install("while");
for_sym = install("for");
eq_sym = install("=");
gets_sym = install("<-");
lpar_sym = install("(");
lbrace_sym = install("{");
call_sym = install("call");
}
if(isSymbol(symb)) {
if(symb == if_sym || symb == for_sym || symb == while_sym ||
symb == lpar_sym || symb == lbrace_sym ||
symb == eq_sym || symb == gets_sym)
return PRINTNAME(symb);
}
return PRINTNAME(call_sym);
}
你可以看到这个函数特例了一些函数调用它们自己的class。
我不认为这些 classes 当前在 R 源代码中使用,但您可以自己使用它们:
f <- function(x) UseMethod("f")
f.if <- function(x) "If statement"
f.while <- function(x) "While loop"
x <- quote(if (a) TRUE)
f(x)
#> "If statement"
y <- quote(while(TRUE){})
f(y)
#> "While loop"
(当然,实际这样做是个坏主意,因为这是该语言的一个极其深奥的角落,没有人会理解它是如何工作的)