2

我有一个关于参考类的问题。如何检查字段分配。

这是我的示例代码:

rm(list=ls(all=TRUE))

setRefClass(
    Class = "A", 
    fields = list(firstValue = "numeric"),
    methods = list(

        initialize = function(..., firstValue = numeric()) {
            setFirstValue(firstValue)
        },

        getFirstValue = function() {
            return(firstValue)
        },

        setFirstValue = function(value) {
            if(length(value) != 0) {
                if(value > 10) {
                    cat("only values lower 10 allowed!\n")
                    firstValue <<- 10
                } else {
                    firstValue <<- value
                }
            } else {
                firstValue <<- 0
            }
        }               
    )
)

test <- getRefClass("A")$new()
test$getFirstValue()
test$firstValue
test$setFirstValue(11)
test$firstValue
test$firstValue <- 11
test$firstValue

我的问题是如何防止它,设置“test$firstValue <- 11”而不检查值。在 S4 中,我会这样解决它:

setGeneric(name = 'setFirstValue<-', def = function(object, value) {standardGeneric('setFirstValue<-')})
setReplaceMethod(
        f = 'setFirstValue',
        signature = 'A',
        definition = function(object, value) {
            object@.firstValue <- value
            validObject(object)
            return(object)
        }
)

and

setReplaceMethod(
    f = "[",
    signature = "A",
    definition = function(x, i ,j , value) {
        if(i == 'firstValue ' || i == 1) {setFirstValue(x) <- value}
    return(x)
    }
)

最后,在“A”的类定义中,“ validity = function(object){ ... }”将被放置。但是我怎么能用参考类来解决这个问题呢?

感谢帮助。

4

1 回答 1

1

setValidity并且显式调用validObject也可以在引用类上使用,

A <- setRefClass("A", fields=list(x="numeric"))

setValidity("A", function(object) {
    if (length(object$x) != 1L || !all(object$x < 11))
        "'x' must be length 1 and < 11"
    else NULL
})

进而

> a = A(x=11)
> validObject(a)
Error in validObject(a) : 
  invalid class "A" object: 'x' must be length 1 and < 11

但在某些方面,您的直接字段访问与直接插槽访问相同

B <- setClass("B", representation(x="numeric"))

setValidity("B", function(object) {
    if (length(object@x) != 1L || !all(object@x < 11))
        "'x' must be length 1 and < 11"
    else NULL
})

> b = B()
> b@x = 11       # no validObject check, just like direct field assignment
> validObject(b)
Error in validObject(b) : 
  invalid class "B" object: 'x' must be length 1 and < 11

因此,作为使用您定义的访问器的编程学科test$setFirstValue(11), 似乎是施加额外有效性条件的最佳方法。

S4 类具有 R 的通常语义——更改时复制的外观——而引用类具有引用语义;这是确定要使用的适当类系统的主要区别和驱动力,即使也存在性能差异。

于 2013-03-15T17:57:35.790 回答