10

有人可以解释为什么在注册的旧式 S3 类上重载运算符不能按预期工作,而在定义新类和重载运算符时确实有效。

如以下示例所示。

这不起作用。

require(ff) 
setOldClass(Classes=c("ff_vector")) 
setMethod( 
  f="*", 
  signature = signature(e1 = c("ff_vector"), e2 = c("ff_vector")), 
  definition = function (e1, e2){ 
        print("S3 setOldClass")
        e1[] * e2[] 
    } 
) 
ff(1:10) * ff(1:10) 
Error in ff(1:10) * ff(1:10) : non-numeric argument to binary operator

但这有效。

setClass("myff_vector", representation(x="ff_vector"))
setMethod( 
  f="*", 
  signature = signature(e1 = c("myff_vector"), e2 = c("myff_vector")), 
  definition = function (e1, e2){ 
        print("S4 setOldClass")
        e1@x[] * e2@x[] 
    } 
) 
new("myff_vector", x = ff(1:10)) * new("myff_vector", x = ff(1:10))
[1] "S4 setOldClass"
[1]   1   4   9  16  25  36  49  64  81 100
4

2 回答 2

0

尝试部分回答:在帮助('方法')中,在通用函数部分中,声明:

可以为大多数原语定义方法,并创建相应的元数据对象来存储它们。对原语的调用仍然直接转到 C 代码,有时会检查适用的方法。“有时”的定义是,对于会话中加载的某个包中的函数,必须检测到方法,并且 对于第一个参数(或对于二元运算符的情况下,对于第二个参数), isS4(x) 为 TRUE 。

回到你的问题,*是一个原始的,并且:

library(ff)
setOldClass("ff_vector")
isS4(ff(1:10))
[1] FALSE

因此,据我了解,即使您使用 setOldClass(),也无法在 S3 类上为原始函数定义方法。

于 2013-10-29T12:48:00.380 回答
0

从这个是否算作答案的问题中并不清楚,但为了记录,运算符可以以简单的 S3 样式重载,没有任何setOldClassor S4

`*.ff_vector` <- function(x, y) {
  print("hi")
  x[] * y[]
}

> ff(1:10) * ff(1:10)
[1] "hi"
[1]   1   4   9  16  25  36  49  64  81 100
于 2018-01-28T21:54:35.583 回答