2016-03-21 9 views
0

Ich habe eine Referenzklasse, die ich als Objekt in einer anderen Referenzklasse verwenden würde. Beispiel:R: Felder in Referenzklassen des Typs Referenzklasse

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() 

Als ich die erste Zeile nach den Kommentar Markierungen aufrufen, erstellt es eine class_2 Objekt mit einem class_1 Objekt innerhalb davon, aber es initialisiert nie die Felder auf das Objekt class_1_item, die den Konstruktor als Teil genannt hat der ersten Zeile. Wenn ich jedoch den Konstruktor direkt in Zeile 2 (außerhalb des Konstruktors der Klasse 2) aufruft, initialisiert er diese Felder einfach. Schließlich, wenn ich den Konstruktor in Zeile 3 ohne Argumente aufruft, greift er nicht einmal auf die Standardargumente und lässt alles leer.

Ich habe das Gefühl, dass es bei R-Klassen etwas Grundlegendes gibt, das sie komplett von C/Python/Java-Klassen unterscheidet, die ich nicht verstehe. Ich verstehe nicht, was das Objekt "class_1" als Objekt bezeichnet, wenn ich den Zuweisungsoperator mit $ setRefClass() $ verwende. Außerdem habe ich das Gefühl, dass ich nicht verstehe, in welchen Fällen der Operator "< - < -" in diesem Zusammenhang gegen den Operator "< -" verwendet werden soll.

Was fehlt mir?

Antwort

1

Der Initialisierungsvorgang für S4-Referenzklassen hat mich immer verwirrt, daher könnte es eine bessere Lösung geben. Sie müssen <<- anstelle von <- verwenden, da der normale Zuweisungsoperator nur eine lokale Zuweisung - lokal für Ihre Init-Methode - vornehmen würde. Sie möchten jedoch die Felder im Objekt ersetzen, die sich in der umschließenden Umgebung einer für Ihr Objekt definierten Methode befinden. Um eine Zuweisung in der umgebenden Umgebung vorzunehmen, benötigen Sie <<-. Eine Alternative ist die Verwendung von .self, die ich zur Veranschaulichung unten verwende - soweit ich weiß, gibt es keinen anderen Unterschied als die Präferenz.

Auch ich modifizierte Ihr Beispiel so, dass der Init-Prozess mit Ihren Erwartungen übereinstimmt. Der Initialisierungsabschnitt der setRefClass-Funktion kann lesenswert sein. Ich habe kein Verständnis dafür, was eine initializer Methode, wie Sie es im Gegensatz zu der initialize Methode definiert, aber ich glaube, es ist das letztere, was Sie wirklich wollen. Desweiteren konnte ich aus dem class_1_version Objekt, auf das Sie sich beziehen, keinen Sinn ergeben, der aber nirgendwo definiert zu sein scheint. Aber ich hoffe, das Folgende hilft trotzdem.

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

Danke! Das muss ein Tippfehler sein, dann sollte $ initializer $ $ initialize $ sein. – ecksc