2012-10-29 86 views
3

我遇到了一些R參考類的行爲,我想解決它。在下面的代碼中,引用類B有兩個引用類A的字段。參考類內的參考類的實例化 - 鎖()和不變性的問題

在B的initialize()方法被調用之前,B中的這些字段似乎被實例化(可能兩次),並帶有參數類A的零參數(默認)版本。然後在B的初始化過程中用實例A的正確版本替換這些實例。問題是,如果我使用B的實例生成器中的lock(),則A中的初始空實例化不能在B中替換。另一個問題是引用類A需要初始化[或缺少(c)測試]中的缺省值。

幫助 - 建議 - 等讚賞。

A <- setRefClass('A', 
    fields = list(
     count = 'numeric' 
    ), 

    methods = list(
     initialize = function (c=0) { 
      cat('DEBUG: A$initialize(c); where c='); cat(c); cat('\n') 
      count <<- c 
     } 
    ) 
) 

instance.of.A <- A$new(10) 
str(instance.of.A) 

B <- setRefClass('B', 
    field = list(
     a = 'A', 
     b = 'A' 
    ), 

    methods = list(
     initialize = function(c) { 
      a <<- instance.of.A 
      b <<- getRefClass('A')$new(c) 
     } 
    ) 
) 

instance.of.b <- B$new(100) 
str(instance.of.b) 

回答

0

借鑑上面的,我使用的解決方案(有點長,因爲類型檢查的):

A <- setRefClass('A', 
    fields = list(
     count = function(x) { 
      if (!missing(x)) { 
       if(class(x) != 'numeric') 
        stop('Class A: count set by non-number') 
       .self$count.private <- x 
      } 
      .self$count.private 
     } 
    ), 

    methods = list(
     initialize = function (c=0) { 
      cat('DEBUG: A$initialize(c); where c='); cat(c); cat('\n') 
      count <<- c 
     } 
    ) 
) 

instance.of.A <- A$new(10) 
str(instance.of.A) 

B <- setRefClass('B', 
    field = list(
     a = function(x) { 
      if (!missing(x)) { 
       if(!inherits(x, 'envRefClass') || class(x)[1] != 'A') 
        stop('Class B: expecting instance of class A') 
       .self$a.private <- x 
      } 
      .self$a.private 
     }, 
     b = function(x) { 
      if (!missing(x)) { 
       if(!inherits(x, 'envRefClass') || class(x)[1] != 'A') 
        stop('Class B: expecting instance of class A') 
       .self$b.private <- x 
      } 
      .self$b.private 
     } 
    ), 

    methods = list(
     initialize = function(c) { 
      a <<- instance.of.A 
      b <<- getRefClass('A')$new(c) 
     } 
    ) 
) 

instance.of.b <- B$new(100) 
str(instance.of.b) 
2

這裏有兩個可能的解決方案:

  1. 不要設置字段屬性:

    B <- setRefClass('B', 
        methods = list(
         initialize = function(c) { 
          .self$a = instance.of.A 
          .self$b =getRefClass('A')$new(c) 
         } 
        ) 
    ) 
    
  2. 組圖場,但使用ANY類:

    B <- setRefClass('B', 
        field = (a="ANY", b="ANY"), 
        methods = list(
         initialize = function(c) { 
          a <<- instance.of.A 
          b <<- getRefClass('A')$new(c) 
         } 
        ) 
    ) 
    

這兩種解決方案的缺點是該類型不是在ab執行,即

B$a = "Fred" 

現在是可能的。

+0

感謝 - 我猜想的答案,你的明顯缺點是在外地使用類似sintax訪問器方法,並在方法的設置部分包含類型檢查。將測試並讓你知道。 –