gpt4 book ai didi

R R6 类和 UseMethod/泛型方法

转载 作者:行者123 更新时间:2023-12-04 14:12:47 24 4
gpt4 key购买 nike

我想使用 R6 类和泛型方法 (UseMethod) 将不同类的小对象(Small1、MyClassA 和 Small2、MyClassB)添加到 MyClass 的 Big 实例中的公共(public)列表(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)

最佳答案

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() .

关于R R6 类和 UseMethod/泛型方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25138436/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com