假设我有:

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将包含foobar实例的所有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而不是名称,但是对于某些钱包来说这可能就足够了。

09-26 06:26