为参考类定义访问器功能

时间:2015-01-19 10:31:25

标签: r

我目前正在探索R Reference Class的可能性,而我正试图绕过定制的访问者功能。字段的手册说明:

  

列表中的元素也可以是存取函数,a   一个参数的函数,如果使用no调用则返回该字段   参数或将其设置为参数的值否则。访问   函数在内部使用,用于系统间接口   应用。他们的定义遵循编写方法的规则   对于班级:他们可以参考其他领域,可以打电话给其他人   此类或其超类的方法。请参阅有关的部分   访问者使用的内部机制的“实现”   功能

我能找到的所有内容都是在file storage的上下文中使用访问函数。习惯于私有内部变量和输入验证,我认为这是输入数据验证的地方,参见下面的示例:

Account <- 
  setRefClass("Account",
              fields = list(data = "list",
                            balance = 
                              function(value){
                                if (missing(value)){
                                  return(data$balance)
                                }else{
                                  if (!is.numeric(value))
                                    stop("You can only set the balance to a numeric value!")
                                  data$balance <<- value
                                }
                              }),
              methods = list(
                withdraw = function(x) {
                  balance <<- balance - x
                },
                deposit = function(x) {
                  balance <<- balance + x
                }
              ))

这可以按预期工作:

> a <- Account$new(balance = 0)
> 
> a$deposit(10)
> a$balance
[1] 10
> 
> a$withdraw(1)
> a$balance
[1] 9
> 
> a$balance <- "a"
 Error in (function (value)  : 
  You can only set the balance to a numeric value! 

我想知道是否有理由不这样做,因为它似乎是一种自然的方法,但手册中没有提到?是否有一种完全隐藏数据变量的好方法,例如在某些时候使用.self <- local({data = list(); .self})

1 个答案:

答案 0 :(得分:0)

我一直在努力解决这个问题,似乎没有办法完全隐藏数据。我在您的示例中注意到的一件事是您仍然可以通过调用以下方式手动更改余额值:

a <- Account$new(balance = 0)   
a$data$balance<-"a"
a$balance
#> [1] "a"

它仍然可以被操纵的原因是我怀疑它不被推荐的原因。当手册描述访问器功能时,它似乎指的是如果你想使用$ accessor(在手册中描述)你得到的功能。示例如下:

Account <- 
  setRefClass("Account",
              fields = list(balance = "numeric"),
              methods = list(
                withdraw = function(x) {
                  balance <<- balance - x
                },
                deposit = function(x) {
                  balance <<- balance + x
                }
              ))
Account$accessors("balance")
a<-Account$new("balance"=0)
# you can now get and set the balance with getBalance() and setBalance(x).
# (it automatically capitalizes your field name) 
a$setBalance(10)
a$getBalance()
# [10]

最后,如果要在getBalance()的{​​{1}}参数中添加额外的检查,则可以随时手动创建和设置setBalance(x) / methods方法。 其中大部分是从setClassRef的文档中推断出来的。 See this link on stackoverflow below which discusses Private Members.