2016-03-21 6 views
0

У меня есть ссылочный класс, который я бы использовал в качестве объекта внутри другого ссылочного класса. Пример:R: Поля в ссылке Классы типа 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 без аргументов, он даже не захватывает аргументы по умолчанию и оставляет все значение null.

Я чувствую, что есть что-то фундаментальное в классах R, что делает их совершенно отличными от классов C/Python/Java, которые я не получаю. Я не понимаю, что объект «class_1» ссылается как объект, когда я использую оператор присваивания с $ setRefClass() $. Кроме того, я чувствую, что не понимаю, в каких случаях оператор «< < -» предназначен для использования в этом контексте по сравнению с оператором «< -».

Что мне не хватает?

ответ

1

Процесс инициализации для ссылочных классов 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 
     } 
    ) 
) 
+0

Спасибо! Это должна быть опечатка, тогда - $ intializer $ должен быть $ initialize $. – ecksc