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

时间:2016-03-21 17:04:11

标签: r oop reference-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行(类2构造函数之外)调用构造函数时,它初始化这些字段就好了。最后,当我在没有参数的情况下调用第3行中的构造函数时,它甚至不会获取默认参数并将所有内容都保留为空。

我觉得R类的基本原理使得它们与我没有得到的C / Python / Java类完全不同。我不明白对象&#34; class_1&#34;当我使用$ setRefClass()$赋值赋值运算符时,它指的是一个对象。此外,我觉得我不知道在什么情况下&#34;&lt;&lt; - &#34;运算符旨在用于此上下文而不是&#34;&lt; - &#34;操作

我错过了什么?

1 个答案:

答案 0 :(得分:3)

S4参考类的初始化过程总是让我感到困惑,因此可能有更好的解决方案。您必须使用<<-而不是<-,因为普通赋值运算符只会进行本地赋值 - 在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
        }
    )
)