R语言中inherits()与%in%匹配class()判断对象类别的差异
R语言两种对象类别判断方式的差异
两种写法存在明确的实际差异,常规类型判断场景优先使用inherits(),不要用%in% class(x)的写法,具体区别如下:
- 核心差异:继承链判断逻辑完全不同
class(x)只会返回对象显式声明的class属性对应的字符向量,%in%仅能匹配到这个向量里直接列出的类名;而inherits()会按照R的类型系统规则,完整遍历整个继承链(包括隐式基础类型父类、S3/S4/R6等所有面向对象系统的继承关系)做判断,不会漏掉隐式继承的父类。
最容易复现的典型反例:
所有多层继承的自定义类、内置特殊类型(比如矩阵属于数组子类型),只要目标类是对象的父类但没有直接列在class属性向量中,两种写法的返回结果都会出现分歧。df <- data.frame(a = 1:3) # data.frame底层基于列表实现,属于list的子类型 inherits(df, "list") # 返回 TRUE "list" %in% class(df) # 返回 FALSE,因为class(df)仅返回 "data.frame" - 返回值稳定性差异
inherits()永远返回长度为1的逻辑值(TRUE/FALSE),可以直接放在if()等条件判断语句中使用,不会出现异常。
如果误把%in%的左右两边写反(写成class(x) %in% "目标类"),当对象有多个class标签时,会返回和class向量等长的逻辑向量,放在条件判断中会触发“条件长度大于1”的警告,甚至得到完全错误的结果。 - 功能与性能差异
inherits()原生支持一次性传入多个类做判断,比如inherits(x, c("data.frame", "tbl_df"))会直接返回x是否属于其中任意一类,不需要额外套any()函数;还可以通过设置which = TRUE返回匹配到的类在继承链中的层级,功能更灵活。inherits()是R核心的C层原生实现,不需要在R层面生成class字符向量再做遍历匹配,判断速度明显快于%in% class(x)的写法,在循环中批量判断对象类型时性能差距更明显。
只有当你明确需要判断某个类名是否显式写在对象的class属性中(比如做特殊的类标签篡改校验场景),才适合用%in% class(x)的写法,常规判断对象是否属于某类的场景,一律用inherits()即可。
内容的提问来源于stack exchange,提问作者core-i9001
相关产品推荐
相关产品推荐

