在R中,`is.list(x)`和`is(x,'list')`之间的行为不同

pjv*_*aar 7 inheritance types r typechecking

以下行为的解释是什么?

is.list(data.frame()) ## TRUE
is(data.frame(),'list') ## FALSE
is(data.frame()) ## "data.frame" "list" "oldClass" "vector"
extends('data.frame','list') ## TRUE
inherits(data.frame(),'list') ## FALSE
Run Code Online (Sandbox Code Playgroud)

Rei*_*son 8

您正在混合使用S3和S4类约定.is并且extends适用于S4类,但由于这些方法已经实现,因此这些类与S3类一起使用.inherits是为S3类编写的,它不适用于具有完全兼容性的S4对象.

inherits有效地将结果class(x)与您在第二个参数中指定的类进行比较.于是

> class(data.frame())
[1] "data.frame"
Run Code Online (Sandbox Code Playgroud)

不包含"list"任何地方所以失败.

另请注意?inherits:

 The analogue of ‘inherits’ for formal classes is ‘is’.  The two
 functions behave consistently with one exception: S4 classes can
 have conditional inheritance, with an explicit test.  In this
 case, ‘is’ will test the condition, but ‘inherits’ ignores all
 conditional superclasses.
Run Code Online (Sandbox Code Playgroud)

另一个混淆是对象的类和该对象的实现.是的,数据框是一个列表,is.list()告诉我们,但在R的S3类世界中,不是data.frame()类."data.frame""list"

至于is(data.frame(),'list'),它不是那个特定的类,"list"因此FALSE.什么is(data.frame())不被记录?is

Summary of Functions:

     ‘is’: With two arguments, tests whether ‘object’ can be treated as
          from ‘class2’.

          With one argument, returns all the super-classes of this
          object's class
Run Code Online (Sandbox Code Playgroud)

因此is(data.frame())显示了类"data.frame"扩展的类(在S4意义上,而不是S3意义上).这进一步解释了extends('data.frame','list')S4世界中的行为,"data.frame"确实扩展了"list"类.