我很惊讶地发现,在舍入函数的文档中,例如round,它们都是S4泛型。与S3泛型相比,这给了它们什么好处?就我所知,它们所做的一切在S3中即使不能做得更好,也可以做得同样好(我认为S3调度比S4更快?)
round
whlutmcx1#
ceiling、floor、round、signif、trunc都是 * 内部 * 的泛型函数,找不到对应的泛型函数对象(类型为"closure",调用UseMethod或standardGeneric),因为为了效率,分派完全在C代码中进行。2这同样适用于通常的算术、数学、逻辑和关系运算符。例如,可以为round定义S3和S4方法,这两个方法都可以被调度,我们已经知道了S3方法round.Date和round.POSIXt:
ceiling
floor
signif
trunc
"closure"
UseMethod
standardGeneric
round.Date
round.POSIXt
> round.Date function (x, ...) { .Date(NextMethod(), oldClass(x)) } <bytecode: 0x13130e7e8> <environment: namespace:base> > identical(round(.Date(0.1)), .Date(0)) [1] TRUE
设计S4方法并不太难:
> setClass("zzz", contains = "character") > x <- new("zzz", "0.1") > round(x) Error in round(x) : non-numeric argument to mathematical function > setMethod("round", "zzz", function(x, digits = 0) round(as.double(x))) > round(x) [1] 0
因此,您所引用的?round中的语句这些都是(内部)通用S4。有点误导,它说你可以为round定义S4方法,并且它们是用C代码调度的,这是真的,但是它没有表达你 * 也 * 可以为round定义S3方法,并且它们 * 也 * 是用C代码调度的。我将避免回答您关于S4相对于S3的好处的更广泛的问题,因为它已经在其他地方详细讨论过(例如here)。此外,该讨论并不真正适用于像round这样的内部泛型函数,这些函数是为了速度而实现的。
?round
1条答案
按热度按时间whlutmcx1#
ceiling
、floor
、round
、signif
、trunc
都是 * 内部 * 的泛型函数,找不到对应的泛型函数对象(类型为"closure"
,调用UseMethod
或standardGeneric
),因为为了效率,分派完全在C代码中进行。2这同样适用于通常的算术、数学、逻辑和关系运算符。例如,可以为
round
定义S3和S4方法,这两个方法都可以被调度,我们已经知道了S3方法round.Date
和round.POSIXt
:设计S4方法并不太难:
因此,您所引用的
?round
中的语句这些都是(内部)通用S4。
有点误导,它说你可以为
round
定义S4方法,并且它们是用C代码调度的,这是真的,但是它没有表达你 * 也 * 可以为round
定义S3方法,并且它们 * 也 * 是用C代码调度的。我将避免回答您关于S4相对于S3的好处的更广泛的问题,因为它已经在其他地方详细讨论过(例如here)。此外,该讨论并不真正适用于像
round
这样的内部泛型函数,这些函数是为了速度而实现的。