【问题标题】:overloading operators when using setOldClass not works as wanted compared to an S4 class与 S4 类相比,使用 setOldClass 时重载运算符无法正常工作
【发布时间】:2013-04-02 09:22:31
【问题描述】:

有人可以解释为什么在注册的旧式 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

【问题讨论】:

  • 这几乎肯定是这个 [stackoverflow.com/questions/55019663/… 问题背后的相同问题(对象本身需要是 S4,在 isS4() 的意义上,至少其中一个需要是 TRUE,并且setOldClass 是不够的)。

标签: r s4


【解决方案1】:

尝试部分回答: 在 help('Methods') 的 Generic Functions 部分中,声明:

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

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

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

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

【讨论】:

    【解决方案2】:

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

    `*.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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-02
      • 1970-01-01
      • 2015-11-27
      相关资源
      最近更新 更多