【问题标题】:R6Class : initialize method raises the error message: "cannot add bindings to a locked environment"R6Class:初始化方法引发错误消息:“无法将绑定添加到锁定的环境”
【发布时间】:2020-06-10 22:53:17
【问题描述】:

我的工作环境:

R version: 3.6.3 (64 bits)
OS: Windows 10 (64 bits)

我正在研究 Hadley Wickham 的高级 R 书籍中的以下练习:

创建一个银行账户 R6 类来存储余额并允许您 存款和取款。

这是我创建的类

library(R6)
BankAccount <- R6Class(
    classname = "BankAccount",
    public = list(
        initialize = function(first_name,
                              last_name,
                              email,
                              balance
                              ) {
            stopifnot(balance >= 0)
            self$balance <- balance
            self$email <- email
            self$first_name <- first_name
            self$last_name <- last_name
        },
        deposit = function(amount) {
            stopifnot(amount > 0)
            self$balance <- self$balance + amount
            invisible(self)
        },
        withdraw = function(amount) {
            stopifnot(amount > 0, self$balance - amount > 0)
            self$balance = self$balance - amount
            invisible(self)
        },
        print = function() {
            cat(
                "first name: ",
                self$first_name,
                "\n",
                "last name: ",
                self$last_name,
                "\n",
                "email : ",
                self$email,
                "\n",
                "current balance : ",
                self$balance,
                "\n"
                )
            invisible(self)
        }
    )
)


my_bank_account <- BankAccount$new(
                                   first_name = "test_firstname",
                                   last_name = "test_lastname",
                                   email = "testemail@somedomain.com",
                                   balance = 140
                               )

上述代码在执行时会引发以下错误:

Error in self$balance <- balance (from #10) : 
  cannot add bindings to a locked environment
> 

我无法理解班级的初始化方法中的问题。我的代码中的初始化函数有什么问题?

【问题讨论】:

  • 这里有来自shiny 应用程序的此错误的任何人,以下答案很有帮助:TLDR 为您的reactiveValues 定义您的字段,例如vals_data &lt;- reactiveValues(Data = NULL)

标签: r r6


【解决方案1】:

好吧,我必须更仔细地阅读 R6Class 文档:

如果公共或私人列表包含任何具有引用的项目 语义(例如,环境),这些项目将被共享 跨类的所有实例。为避免这种情况,为此添加一个条目 具有“NULL”初始值的项目,然后在“初始化”方法中, 实例化对象并分配它

我的代码的问题是我只在构造函数中声明了字段,但显然它们必须首先声明,在初始化函数之外,由 NULL 分配,然后在初始化程序内部由相应的函数参数分配。所以这是我班级的正确和新版本

library(R6)
BankAccount <- R6Class(
    classname = "BankAccount",
    public = list(
        ## I had forgotten to write the
        ## following 4 lines in the previous
        ## version and apparently this caused
        ## the problem.
        balance = NULL,
        email = NULL,
        first_name = NULL,
        last_name = NULL,
        ##
        ##
        initialize = function(first_name,
                              last_name,
                              email,
                              balance
                              ) {
            stopifnot(balance >= 0)
            self$balance <- balance
            self$email <- email
            self$first_name <- first_name
            self$last_name <- last_name
        },
        deposit = function(amount) {
            stopifnot(amount > 0)
            self$balance <- self$balance + amount
            invisible(self)
        },
        withdraw = function(amount) {
            stopifnot(amount > 0, self$balance - amount > 0)
            self$balance = self$balance - amount
            invisible(self)
        },
        print = function() {
            cat(
                "first name: ",
                self$first_name,
                "\n",
                "last name: ",
                self$last_name,
                "\n",
                "email : ",
                self$email,
                "\n",
                "current balance : ",
                self$balance
                )
            invisible(self)
        }
    )
)    
my_bank_account <- BankAccount$new(
                                       first_name = "test_firstname",
                                       last_name = "test_lastname",
                                       email = "testemail@somedomain.com",
                                       balance = 140
                                   )
    print(my_bank_account)

这一次代码运行没有任何问题。

【讨论】:

    猜你喜欢
    • 2019-12-11
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多