在 R6 上实施 S3 调度的正确方法 类

Proper way to implement S3 dispatch on R6 classes

我有一个 R6 class,我想为它添加一个 S3 方法。我找到的文档简要提到,为了在 R6 上使用 S3 调度,你必须有 class = TRUE,但我找不到应该如何完成的示例。

根据经验,我确实看到简单地以 s3generic.r6class 形式编写 S3 方法是可行的,但我想知道这是否确实是为 [=13] 编写 S3 方法的正确方法=].

例如,假设我有一个 R6 class 增强了 list

library(R6)

R6list <- R6Class(
  "R6list",
  public = list(
    orig = NULL,
    initialize = function(x) {
      self$orig <- x
    }
  )
)

问题 1

自然是想提供获取底层列表的方法,所以想加一个as.list方法。在 class 中同时添加 S3 泛型和 as.list public 函数是标准的吗?我的直觉答案是两者都加。

R6list <- R6Class(
  "R6list",
  public = list(
    orig = NULL,
    initialize = function(x) {
      self$orig <- x
    },
    as.list = function() {
      self$orig
    }
  )
)

as.list.R6list <- function(x, ...) {
  x$as.list()
}

所以现在如果我有一个对象 mylist <- R6list$new(as.list(letters[1:5])),我可以调用 as.list(mylist)mylist$as.list()。其中一个比另一个更受欢迎吗?

问题 2
R6 classes 编写一个 S3 方法有什么特别之处,或者我上面写的方法是否足够且正确?我不确定 S3 方法是否必须在 class 定义之外编写,或者 R6 是否以某种方式提供了一种在其中编写 S3 方法的方法,以便所有与 class 相关的代码都已本地化。

关于这个on Github,我问过R6的作者Winston Chang。按照他的说法,上面问题1提供的代码是R6的S3方法的正确写法类.