假设我有:
Foo <- R6::R6Class("Foo")
Bar1 <- R6::R6Class("Bar1", inherit = "Foo")
Bar2 <- R6::R6Class("Bar2", inherit = "Foo")
f <- Foo$new()
答:我可以做点什么
R6::findChildren("Foo")
[1] "Bar1" "Bar2"
(我认为这与R, R6, Get Full Class Name from R6Generator Object相同,但包括在内是全面的)
我可以做点什么
R6::findInstances("Foo")
[1] "f"
C.我可以做点什么
b1 <- Bar1$new()
b2 <- Bar2$new()
R6::findInstances("Foo")
[1] "f" "b1" "b2"
最佳答案
A不了解R6中的内置功能可以归档这些任务。
但是,有一种方法可以通过使用具有引用语义的成员自己编写类似的功能。原因是引用成员将在该类的所有实例之间共享,如here所述
如果您的R6类包含也具有引用语义的任何字段(例如,其他R6对象和环境),则应在initialize方法中填充这些字段。如果该字段直接在类定义中设置为引用对象,则该对象将在R6对象的所有实例之间共享。
在下文中,我将仅介绍B.和C.,因为A.已被回答here(如问题中所述)。
基本设定
您必须“直接在类定义中”添加具有引用语义的成员,并在创建新实例时更改该成员。
library(R6)
foo <- R6Class(
public = list(
info = new.env(), # member with reference semantics
initialize = function(ID){
self$info$IDs = c(self$info$IDs, ID) # "push_back" new ID
}
)
)
a_name <- foo$new("a_id")
b_name <- foo$new("b_id")
a_name$info$IDs
# [1] "a_id" "b_id"
b_name$info$IDs
# [1] "a_id" "b_id"
请注意,此代码将为您提供实例ID,而不是实例名称。
遗产
通过从父类(也称为
super
类)调用ID管理器,可以很简单地继承此行为。bar <- R6Class(
inherit = foo,
public = list(
initialize = function(ID){
super$initialize(ID) # use ID management from the super class
}
)
)
c_name <- bar$new("c_id")
c_name$info$IDs
# [1] "a_id" "b_id" "c_id"
现在,列表
IDs
将包含foo
或bar
实例的所有ID。一个不错的包装
如果要从
foo
对象而不是其实例获取ID,则可以使用以下内容# add a new "static" function to the R6Class/environment foo
foo$getIDs <- function(){
dummy_instance <- foo$new(NULL) # inserting NULL in an unnamed list does nothing
dummy_instance$info$IDs
}
foo$getIDs()
# [1] "a_id" "b_id" "c_id"
我知道这不是您要的,因为这种方式会给您ID而不是名称,但是对于某些钱包来说这可能就足够了。