r - 多个类的 S3 运算符重载

标签 r operator-overloading r-s3

我定义了两个类,它们可以成功添加两个自己的对象或一个数字和一个自己的对象。

a <- structure(list(val = 1), class = 'customClass1')
b <- structure(list(val = 1), class = 'customClass2')
`+.customClass1` <- function(e1, e2, ...){
  val1 <- ifelse(is.numeric(e1), e1, e1$val)
  val2 <- ifelse(is.numeric(e2), e2, e2$val)
  val_res <- val1  + val2
  print('customClass1')
  return(structure(list(val = val_res), class = 'customClass1'))
}
`+.customClass2` <- function(e1, e2, ...){
  val1 <- ifelse(is.numeric(e1), e1, e1$val)
  val2 <- ifelse(is.numeric(e2), e2, e2$val)
  val_res <- val1  + val2
  print('customClass2')
  return(structure(list(val = val_res), class = 'customClass1'))
}
print.customClass1 <- function(x, ...){
  print(x$val)
}
print.customClass2 <- function(x, ...){
  print(x$val)
}
a + a
# [1] 2
a + 1
# [1] 2
b + b
# [1] 2
1 + b
# [1] 2

但很明显,当我尝试添加两个自定义类时会出错。
a + b
# Error in a + b : non-numeric argument to binary operator
# In addition: Warning message:
# Incompatible methods ("+.customClass1", "+.customClass2") for "+" 

我可以只为 customClass1 定义一个函数,但是当我尝试添加两个 customClass2 对象时,该函数将不起作用。有没有办法将一个功能优先于另一个功能?

R 似乎通过将我的函数优先于基本函数(例如数字或整数类型)来自然地做到这一点。当两个参数之一具有 customClass 类型时,R 会自动将其重定向到我的函数而不是默认函数。

最佳答案

?base::Ops 的详细信息部分讨论了 R 如何选择调度哪个方法。

The classes of both arguments are considered in dispatching any member of this group. For each argument its vector of classes is examined to see if there is a matching specific (preferred) or 'Ops' method. If a method is found for just one argument or the same method is found for both, it is used. If different methods are found, there is a warning about 'incompatible methods': in that case or if no method is found for either argument the internal method is used.



如果 customClass1customClass2是相关的,您可以使用一个虚拟类来允许使用两个不同的类进行操作。例如,您可以混合 POSIXctPOSIXlt因为它们都继承自 POSIXt .这记录在 ?DateTimeClasses :

"POSIXct" is more convenient for including in data frames, and "POSIXlt" is closer to human-readable forms. A virtual class "POSIXt" exists from which both of the classes inherit: it is used to allow operations such as subtraction to mix the two



例如:
class(pct <- Sys.time())
# [1] "POSIXct" "POSIXt"
Sys.sleep(1)
class(plt <- as.POSIXlt(Sys.time()))
# [1] "POSIXlt" "POSIXt"
plt - pct
# Time difference of 1.001677 secs

如果这些类不以这种方式关联,Emulating multiple dispatch using S3 for “+” method - possible? 的答案中有一些很好的信息。 .

关于r - 多个类的 S3 运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43066501/

相关文章:

c++ - 使用重载赋值运算符

r - 坚持自动绘图 S3 方法的定义

在Databricks中使用sparklyr注册临时表

r - 如何调整随机森林代码以进行质量预测

c++ - 继承在类外定义的运算符

r - 修改 S3 对象而不返回它?

r - 运算符重载在 R 包中停止工作

r - 在 R 中,从 df 中采样 n 行,其中某个列具有非 NA 值(有条件地采样)

r - 如何使用 R 找到 2 列的中位数?

java - printf 运算符中使用 % 是否重载?如果不是,那是什么?