2013-03-15 28 views
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 

我的問題是我怎麼能阻止它,說:「測試$ firstValue < - 11」,而沒有設置檢查值。 在S4,我會解決這個問題是這樣的:

setGeneric(name = 'setFirstValue<-', def = function(object, value) {standardGeneric('setFirstValue<-')}) 
setReplaceMethod(
     f = 'setFirstValue', 
     signature = 'A', 
     definition = function(object, value) { 
      [email protected] <- 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){ ... }」將被放置。但我怎麼可以用參考類來解決這個問題?

感謝您的幫助。

回答

1

setValidityvalidObject顯式調用,可以參考類使用,也

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([email protected]) != 1L || !all([email protected] < 11)) 
     "'x' must be length 1 and < 11" 
    else NULL 
}) 

> b = B() 
> [email protected] = 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語義 - 在變化上出現拷貝 - 而引用類具有引用語義;這是決定使用適當的班級制度的主要差異和驅動力,即使性能差異也存在。

+0

我感謝你指出,我也可以使用validObject()。但正如你已經寫了,我不能阻止直接訪問。問題是,與「object @ slot < - 」相比,「object $ field < - 」與其他人使用得非常快。我認爲這應該改進。 – exitia 2013-03-18 08:50:13