比如,我正在实现一个自定义的S3类,名为“myclass”:
myvec <- 1:5
class(myvec) <- "myclass"
我定义了Group Ops泛型,以便在标准操作后保留类。
Ops.myclass <- function(e1, e2) {
if(is(e1, "myclass")) {
e1 <- unclass(e1)
structure(NextMethod(), class="myclass")
} else if(is(e2, "myclass")) {
e2 <- unclass(e2)
structure(NextMethod(), class="myclass")
}
}
现在我的类被保留了,例如,加法:
然而,当我对有自己的Group泛型的对象这样做时,我遇到了问题:
myvec + Sys.Date()
[1] 19454 19455 19456 19457 19458
attr(,"class")
[1] "myclass"
Warning message:
Incompatible methods ("Ops.myclass", "+.Date") for "+"
它不仅产生警告,而且结果也不同:
unclass(myvec) + Sys.Date()
[1] "2023-04-07" "2023-04-08" "2023-04-09" "2023-04-10" "2023-04-11"
问题:如何解决这个警告,并使这个操作返回与myvec
没有类时相同的结果?
基本上,我希望myclass
有自己的组泛型,但在冲突的情况下,要服从,并在冲突时优先考虑其他类。
1条答案
按热度按时间8cdiaqws1#
AFAICT,你在R〈4.3.0的时候运气不好。我打算建议定义S4方法,比如:
因为S4通用函数在S3分派之前执行S4分派(如果它们也是S3通用的)。
但是我记得
Ops
组的所有成员都是内部泛型的,所以当两个参数都不是S4对象时,就不会分派S4方法,就像<zzz> + <Date>
的情况一样。R 4.3.0引入了一个新的通用函数
chooseOpsMethod
,允许用户指定如何为Ops
组的成员解决S3调度歧义。它在?Ops
中有文档说明,当然也在?chooseOpsMethod
中。我假设你已经阅读了相关章节,并建议如下:这是因为没有
chooseOpsMethod.Date
,而且chooseOpsMethod.default
无条件返回FALSE
。其他人可能会注册一个chooseOpsMethod.Date
返回TRUE
,破坏<Date> + <zzz>
的行为,但这就是依赖S3而不是S4所冒的风险...