3

我从 R 参考类中遇到了一些我想解决的行为。在下面的代码中,引用类 B 中有两个引用类 A 的字段。

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

2 回答 2

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

这两种解决方案的缺点是类型不是在aand中强制执行的b,即

 B$a = "Fred"

现在是可能的。

于 2012-11-08T21:04:38.403 回答
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)
于 2012-11-08T22:52:09.610 回答