我想使用R6类和泛型方法(UseMethod
)将不同类(Small1,MyClassA和Small2,MyClassB)的小对象添加到MyClass的Big实例内的公共列表(MyListA和MyListB)。
这适用于创建(Big是使用Small1和-2创建的),但之后失败:
> Big$AddObj(Small3) #produces:
Error in UseMethod("AddObj", x) : no applicable method for 'AddObj'
applied to an object of class "c('MyClassA', 'R6')"
我不太确定我的错误是什么。以后如何为其他对象调用AddObj-Method?建议将非常感谢。
require('R6')
MyClass <- R6Class("MyClass",
public = list(
initialize = function(...) {
for (x in list(...)) {AddObj(x)}
},
AddObj = function(x) {UseMethod("AddObj", x)},
AddObj.MyClassA = function(x) {
MyListA <<- c(MyListA, list(x))},
AddObj.MyClassB = function(x) {
MyListB <<- c(MyListB, list(x))},
AddObj.default = function(x) {
otherObjects <<- c(otherObjects, list(x))},
Show = function() {
print(methods(AddObj))
if (length(MyListA)>0) print(MyListA)
if (length(MyListB)>0) print(MyListB)
},
MyListA = list(),
MyListB = list(),
otherObjects = list()
)
)
MyClassA <- R6Class("MyClassA",
public = list(
name = NA,
initialize = function(input) {
if (!missing(input)) name <<- as.character(input)}
))
MyClassB <- R6Class("MyClassB",
public = list(
name = NA,
initialize = function(input) {
if (!missing(input)) name <<- as.character(input)}
))
Small1 <- MyClassA$new("MyName1")
Small2 <- MyClassB$new("MyName2")
Big <- MyClass$new(Small1, Small2)
Big$Show()
Small3 <- MyClassA$new("MyNewName")
Big$AddObj(Small3)
答案 0 :(得分:8)
R6对象中没有S3调度,但您可以像这样使用if-else语句:
library('R6')
MyClass <- R6Class("MyClass",
portable = FALSE,
public = list(
initialize = function(...) {
for (x in list(...)) {AddObj(x)}
},
AddObj = function(x) {
if (inherits(x, "MyClassA"))
MyListA <<- c(MyListA, list(x))
else if (inherits(x, "MyClassB"))
MyListB <<- c(MyListB, list(x))
else
otherObjects <<- c(otherObjects, list(x))
},
Show = function() {
if (length(MyListA)>0) print(MyListA)
if (length(MyListB)>0) print(MyListB)
},
MyListA = list(),
MyListB = list(),
otherObjects = list()
)
)
MyClassA <- R6Class("MyClassA",
portable = FALSE,
public = list(
name = NA,
initialize = function(input) {
if (!missing(input)) name <<- as.character(input)}
))
MyClassB <- R6Class("MyClassB",
portable = FALSE,
public = list(
name = NA,
initialize = function(input) {
if (!missing(input)) name <<- as.character(input)}
))
Small1 <- MyClassA$new("MyName1")
Small2 <- MyClassB$new("MyName2")
Big <- MyClass$new(Small1, Small2)
Big$Show()
Small3 <- MyClassA$new("MyNewName")
Big$AddObj(Small3)
Big$Show()
另请注意,我使用了portable=FALSE
设置,这是刚刚添加到R6开发版本的设置。有关详细信息,请参阅https://github.com/wch/R6/issues/16。
更新:事实证明我有点错误 - 在R6对象中有S3调度,但如果使用$
调用该函数则不会使用它,如Big$AddObj(Small3)
中所示。您可以使用类似eval(quote(AddObj(Small3)), envir = Big)
之类的东西来使用它,但这显然不是很好。最好使用if-else并使用inherits()
。