R:引用中的字段 Class 类型为引用 Class

R: Fields in Reference Classes of type Reference Class

我有一个引用 class,我想将其用作另一个引用 class 中的对象。示例:

class_1 <- setRefClass( Class = "class_1"
    , fields = list(nickname = "character", version = "character" )
    , methods = list(
      initializer = function(nickname, version) {
        nickname <<- nickname
        version <<- version
      }
    )
)

class_2 <- setRefClass( Class = "class_2"
    , fields = c( version = "character"
                  , nickname = "character"
                  , class_1_item = "class_1" )
    , methods = list(
      initializer = function(class_2_nickname = "B", class_2_version = "V2") {
        class_1_item <<- class_1$new(class_2_nickname, class_1_version)
        nickname <<- class_2_nickname
        version <<- class_2_version
      }
    )

)

#######

class_2_obj <- class_2$new(nickname = "A", version = "V1")

class_1_obj <- class_1$new(nickname = "A", version = "V1")

class_2_obj2 <- class_2$new()

当我调用注释标记后的第一行时,它会创建一个 class_2 对象,其中包含一个 class_1 对象,但它从未将字段初始化为对象 class_1_item 的构造函数作为第一行的一部分被调用。然而,当我在第 2 行(在 class 2 构造函数之外)直接调用构造函数时,它会很好地初始化这些字段。最后,当我在第 3 行调用不带参数的构造函数时,它甚至不获取默认参数并将所有内容留空。

我觉得 R classes 有一些基本的东西使它们与 C/Python/Java classes 完全不同,我没有得到。当我将赋值运算符与 $setRefClass()$ 一起使用时,我不明白对象 "class_1" 指的是什么对象。另外,我觉得我不明白在这种情况下“<<-”运算符与“<-”运算符相比在什么情况下要使用。

我错过了什么?

S4引用的初始化过程类一直让我很困惑,所以可能有更好的解决方案。您必须使用 <<- 而不是 <- 因为 normal 赋值运算符只会进行本地赋值 - 对您的 init 方法而言是本地的。但是,您想替换对象中的字段,这些字段位于为您的对象定义的任何方法的封闭环境中。要在封闭环境中进行分配,您需要 <<-。另一种方法是使用 .self,我将其用于下面的说明 - 据我所知,除了偏好之外没有其他区别。

我还修改了您的示例,使 init 过程符合您的期望。 setRefClass 函数的初始化部分可能值得一读。我不了解你定义的 initializer 方法与 initialize 方法相比有什么作用,但我相信你真正想要的是后者。此外,我对您所指的 class_1_version 对象没有任何意义,但似乎无处定义。但无论如何,我希望以下内容有所帮助。

class_1 <- setRefClass( 
    Class = "class_1", 
    fields = list(nickname = "character", version = "character" ), 
    methods = list(
        initialize=function(nickname = NA_character_, version = NA_character_) {
            .self$nickname <- nickname
            .self$version <- version
        }
    )
)

class_2 <- setRefClass(
    Class = "class_2", 
    fields = c(
        version = "character", 
        nickname = "character", 
        class_1_item = "class_1"
    ), 
    methods = list(
        initialize=function(nickname = NA_character_, version = NA_character_) {
            .self$class_1_item <- class_1$new(nickname, version)
            .self$nickname <- nickname
            .self$version <- version
        }
    )
)