【问题标题】:Instantiation of reference classes within reference classes - problems with lock() and immutability引用类中引用类的实例化 - lock() 和不变性的问题
【发布时间】:2012-10-29 04:38:12
【问题描述】:

我从 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)

【问题讨论】:

    标签: r reference-class


    【解决方案1】:

    这里有两种可能的解决方案:

    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"
    

    现在可以了。

    【讨论】:

    • 谢谢-我怀疑您明显缺点的答案是在字段访问器方法中使用类似的sintax,并在方法的设置部分中包含类型检查。将进行测试并通知您。
    【解决方案2】:

    综合以上,我使用的解决方案是(由于类型检查有点长):

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多