用 Class 和 return 相同的实例初始化 R6 class Class

Initialize R6 class with an instance of Class and return the same Class

给定 R6 class Class1 及其 initialize 功能,我希望能够传递相同 class 和 [=28= 的实例] 直接。

像这样:

if("Class1" %in% class(x)) x
else Class1$new(x)

但是在 R6 class 的 initialize 函数中,它应该像这样工作

# This script does not work
# Definition of the class
Class1 = R6::R6Class("Class1",
                     public=list(
                       initialize = function(x){
                         # This line does not work
                         if("Class1"%in%class(x)) return(x)
                       }
                     ))
# Initiate an instance from scratch
foo = Class1$new()
# Initiate an instance through another instance
bar = Class1$new(foo)
# The two should be the same
identical(foo, bar)
#> TRUE

在R6的当前状态下,这似乎是不可能的。检查原始代码 github.com/r-lib/R6/blob/master/R/new.R 。最重要的是应用初始化的第 154 行和返回 public_bind_env 的第 194 行。问题是,即使使用超级分配,我认为我们也无法覆盖它,因为这里所有的东西都是从一个新的空环境构建的,它有自己的地址。 这种使用包装器的解决方案在市场上被广泛使用,它正在做它应该做的事情:

class1 <- function(x = NULL) {
  
  if(inherits(x, "Class1")) x else Class1$new(x)
    
}

Class1 = R6::R6Class("Class1",
                     public=list(
                       initialize = function(x = NULL){
                       }
                     ))
# Initiate an instance from scratch
foo = class1()
# Initiate an instance through another instance
bar = class1(foo)
# The two should be the same
identical(foo, bar)
#> TRUE