了解attr(x,“ class”)和class(x)之间的区别

时间:2019-02-23 13:32:27

标签: r class oop primitive

背景

我正在查看RomainFrançois提出的jazz软件包。 Romain使用以下语法定义函数 Console.SetOut(new StreamWriter(File.Create("d:/your_output.txt"), Encoding.UTF8) { AutoFlush=true});

is_bare_vector

问题

对于:is_bare_vector <- function(x) { is_vector(x) && !is.object(x) && is.null(attr(x, "class")) }

x <- 1

位置:

attr(x, "class")
# NULL

我想了解为什么这两个函数提供不同的答案? class(x) # [1] "numeric" 上的帮助引用了?attr

?class

  

请注意,某些属性(即?attrclasscommentdim,   dimnamesnamesrow.names)受到特殊对待并有限制   在可以设置的值上。 (请注意,这对于级别而言并非如此   应该通过级别替换功能为因子设置)。

tsp

  

许多R对象都有一个class属性,一个字符向量给出了   对象所继承的类的名称。 (功能   ?classoldClass获取并设置属性,该属性也可以是   直接完成。)

1 个答案:

答案 0 :(得分:8)

您只需要在help("class")中进一步阅读:

  

如果对象没有类属性,则它具有隐式类,尤其是“矩阵”,“数组”,“函数”或“数字”或typeof(x)的结果(类似于mode( x))

显然,如果class属性为class(),则NULL还将返回隐式类。让我们来看看C source code- 我们看到,如果class属性的长度为0,它将得到隐式类。

SEXP R_data_class(SEXP obj, Rboolean singleString)
{
    SEXP value, klass = getAttrib(obj, R_ClassSymbol);
    int n = length(klass);
    if(n == 1 || (n > 0 && !singleString))
    return(klass);
    if(n == 0) {
    SEXP dim = getAttrib(obj, R_DimSymbol);
    int nd = length(dim);
    if(nd > 0) {
        if(nd == 2)
        klass = mkChar("matrix");
        else
        klass = mkChar("array");
    }
    else {
      SEXPTYPE t = TYPEOF(obj);
      switch(t) {
      case CLOSXP: case SPECIALSXP: case BUILTINSXP:
        klass = mkChar("function");
        break;
      case REALSXP:
        klass = mkChar("numeric");
        break;
      case SYMSXP:
        klass = mkChar("name");
        break;
      case LANGSXP:
        klass = lang2str(obj, t);
        break;
      default:
        klass = type2str(t);
      }
    }
    }
    else
    klass = asChar(klass);
    PROTECT(klass);
    value = ScalarString(klass);
    UNPROTECT(1);
    return value;
}