R 引用类中引用类的实例化-lock()和不变性问题

R 引用类中引用类的实例化-lock()和不变性问题,r,reference-class,R,Reference Class,我在R参考课程中遇到了一些行为,我希望能够解决这些问题。在下面的代码中,引用类B中有两个引用类A的字段 在调用B的initialize()方法之前,B中的这些字段似乎被引用类a的零参数(默认)版本实例化(可能两次)。然后,在B的初始化过程中,用实例A的正确版本替换这些实例。问题是,如果我使用B的实例生成器中的lock(),则B中不能替换A的初始空实例化。另一个问题是,引用类A在初始化[或缺少(c)测试]中需要一个默认值 感谢您的帮助、建议等 A <- setRefClass('A',

我在R参考课程中遇到了一些行为,我希望能够解决这些问题。在下面的代码中,引用类B中有两个引用类A的字段

在调用B的
initialize()
方法之前,B中的这些字段似乎被引用类a的零参数(默认)版本实例化(可能两次)。然后,在B的初始化过程中,用实例A的正确版本替换这些实例。问题是,如果我使用B的实例生成器中的
lock()
,则B中不能替换A的初始空实例化。另一个问题是,引用类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)

A以下是两种可能的解决方案:

  • 不设置字段属性:

    B <- setRefClass('B',
        methods = list(
            initialize = function(c) {
              .self$a = instance.of.A
              .self$b =getRefClass('A')$new(c)
            }
         )
     )
    
  • 这两种解决方案的缺点是在
    a
    b
    中没有强制执行该类型,即

     B$a = "Fred"
    

    现在是可能的。

    根据上述内容,我使用的解决方案是(由于类型检查,有点长):


    A谢谢-我想你明显缺点的答案是在字段访问器方法中使用类似的sintax,并在方法的设置部分包含类型检查。将测试并让您知道。
    
     B$a = "Fred"
    
    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)