0

我正在研究一个自定义R6Class,它将成为我的 R 包的主要结构。但问题在于:

setMethod('+', signature("MyClass"), function(e1, e2)1)

或者

setMethod('+', signature("R6"), function(e1, e2)1)

不工作,因为当我跑步时

a = MyClass$new()
a + a

我收到以下错误Error in a + a : non-numeric argument to binary operator

我让它工作的唯一方法就是这样

`+.MyClass` = function(e1, e2) { return (1) }

但这没有用,因为在library(MyClass)空环境+.MyClass中从头开始加载包时 ( ) 未定义。

那么,如何以正确的方式重载 R6 类的运算符呢?

以防万一,片段

MyClass = R6Class(
   "MyClass",
   public = list(
      initialize = function() {
      }
   ),
   private = list(
   )
)

setMethod('+', signature("MyClass"), function(e1, e2)1)
a = MyClass$new()
a+a
4

1 回答 1

2

当你加载包时,+.MyClass应该绝对可用,假设你已经导出了函数。1

我可以用一个我使用的最小示例来证明这一点devtools——我不能推荐足够的使用 devtools 来创建包。首先,我创建了一个最小的包结构:

devtools::create("dummypack", rstudio = FALSE)

然后我在“dummypack/R/”文件夹“MyClass.R”中添加一个 R 文件:

#' @export
MyClass = R6::R6Class(
    "MyClass",
    public = list(
        initialize = function() {
        }
    ),
    private = list(
    )
)

#' @export
`+.MyClass` = function(e1, e2) { return (1) }

这里的#' @export标签很关键;2要使此功能可用,您需要将其导出到“dummypack/NAMESPACE”文件中(请参阅Hadley Wickham 的 R 包的命名空间章节)。你需要你的 NAMESPACE 文件看起来像

export(MyClass)
export(`+.MyClass`)

确保类和重载的运算符+被导出。或者你可以有一个像

exportPattern("^[^\\.]")

导出不以 a 开头的所有内容.(这是最初由 生成的 NAMESPACE 文件devtools::create())。因此,如果您使用devtools(和 Roxygen -- roxygen2),您需要自己编辑 NAMESPACE 文件以确保您的函数已导出。

然后我跑

devtools::install("dummypack/")

在一个新的 R 会话中,我运行:

library(dummypack)
a = MyClass$new()
a+a
# [1] 1

表明你得到了你想要的结果。


1我原以为这个问题很容易被标记为重复。这个问题是我找到的最接近的问题,但似乎有点过于针对 Roxygen。

2请注意,如果您使用的是 Roxygen,这些标签仅对您的 NAMESPACE 文件有帮助(如果您使用的是 ,这将起作用devtools::document())。此外,对于我展示的最小示例,标签在技术上不是必需的,因为生成的默认 NAMESPACEdevtools::create()仅具有exportPattern("^[^\\.]")如上所述的行。但是,在典型情况下,您需要这些标记,无论哪种方式,重要的是最终在 NAMESPACE 文件中 - 您需要export()NAMESPACE 中的显式语句或诸如exportPattern("^[^\\.]").

于 2018-03-24T12:59:19.083 回答