R参考类中的私人会员

aka*_*nom 11 r reference-class

是否可以在R引用类中包含私有成员字段.玩我的一些在线示例:

> Account <- setRefClass(    "ref_Account"
>      , fields = list(
>       number = "character"
>       , balance ="numeric")
>      , methods = list( 
>     deposit <- function(amount) {
>       if(amount < 0)   {
>         stop("deposits must be positive")
>       }
>       balance <<- balance + amount
>     }
>     , withdraw <- function(amount) {
>       if(amount < 0)   {
>         stop("withdrawls must be positive")
>       }
>       balance <<- balance - amount
>     }       
>   ) )
> 
> 
> tb <- Account$new(balance=50.75, number="baml-029873") tb$balance
> tb$balance <- 12 
> tb$balance
Run Code Online (Sandbox Code Playgroud)

我讨厌我可以直接更新天平的事实.也许那个旧的纯粹的OO在我身上,我真的希望能够使平衡变得私密,至少从课堂外不可设定.

思考

Seb*_*ian 5

为了解决隐私问题,我创建了一个自己的类“Private”,它具有访问对象的新方法,即$[[。如果客户端尝试访问“私有”成员,这些方法将引发错误。私人成员通过名称(前导句点)进行标识。由于引用对象是 R 中的环境,因此可以解决此问题,但这是我目前的解决方案,我认为使用类提供的 get/set 方法更方便。因此,这更像是该问题的“课堂外难以设置”的解决方案。

我已将其组织在 R 包内,因此以下代码利用该包并修改上面的示例,以便对 进行赋值会tb$.balance产生错误。我还使用了该函数Class,它只是一个包装器,setRefClass因此它仍然在方法包提供并在问题中使用的 R 参考类的范围内。

devtools::install_github("wahani/aoos")
library("aoos")

Account <- defineRefClass({
    Class <- "Account"
    contains <- "Private"

    number <- "character"
    .balance <- "numeric"

    deposit <- function(amount) {
        if(amount < 0) stop("deposits must be positive")
        .balance <<- .balance + amount
    }

    withdraw <- function(amount) {
        if(amount < 0) stop("withdrawls must be positive")
        .balance <<- .balance - amount
    }
})

tb <- Account(.balance = 50.75, number = "baml-029873") 
tb$.balance # error
tb$.balance <- 12 # error
Run Code Online (Sandbox Code Playgroud)


csg*_*pie 3

这个答案不适用于 R > 3.00,所以不要使用它!

如前所述,您不能拥有私有成员字段。但是,如果您使用初始化方法,则余额不会显示为字段。例如,

Account = setRefClass("ref_Account", 
                       fields = list(number = "character"),
                       methods = list(
                           initialize = function(balance, number) {
                               .self$number = number
                               .self$balance = balance
                           })
Run Code Online (Sandbox Code Playgroud)

和以前一样,我们将创建一个实例:

tb <- Account$new(balance=50.75, number="baml-0029873")
##No balance
tb

Reference class object of class "ref_Account"
Field "number":
[1] "baml-0029873"
Run Code Online (Sandbox Code Playgroud)

正如我所提到的,它并不是真正的私有,因为您仍然可以执行以下操作:

R> tb$balance
[1] 50.75
R> tb$balance = 12 
R> tb$balance
[1] 12
Run Code Online (Sandbox Code Playgroud)

  • 为什么这不适用于 R &gt; 3.00?现在可以原生做私有成员吗? (2认同)