使用R6,我如何找到从某些超类继承的类和对象?

时间:2017-07-07 01:31:30

标签: r oop r6

假设我有:

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相同,但包括它是全面的)

B中。我可以做点什么吗

R6::findInstances("Foo")
[1] "f"

℃。我可以做点什么吗

b1 <- Bar1$new()
b2 <- Bar2$new()
R6::findInstances("Foo")
[1] "f" "b1" "b2"

2 个答案:

答案 0 :(得分:1)

我不知道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 而非实例名称

继承

通过从父类(a.k.a。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"

我知道这不是你要求的,因为这个appriach会给你ID而不是名字但是对于一些purpuses这可能就足够了。

答案 1 :(得分:1)

我认为此帮助程序功能可以满足您的需求:

findR6_obj <- function(className=NULL){
    classList <- eapply(.GlobalEnv, class)
    obj_R6 <- classList[vapply(classList, function(ele) "R6" %in% unlist(ele), logical(1))]
    if (is.null(className)) {
        return(obj_R6)
    } else {
        names(obj_R6[vapply(obj_R6, function(ele) className %in% unlist(ele), logical(1))])
    }
}

如果不带参数使用它,它将返回全局环境中的所有R6对象(以及有关其类的更多信息),并且如果将其与className的参数一起使用,请说{ {1}},它将返回包含Foo的R6类。

您可以修改它,使其仅在某些特定环境中显示。