R6Class:初始化方法引发错误消息:"cannot add bindings to a locked environment"

R6Class : initialize method raises the error message: "cannot add bindings to a locked environment"

我的工作环境:

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

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

Create a bank account R6 class that stores a balance and allows you to deposit and withdraw money.

这是我创建的class

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
> 

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

嗯,我不得不更仔细地阅读 R6Class 文档:

If the public or private lists contain any items that have reference semantics (for example, an environment), those items will be shared across all instances of the class. To avoid this, add an entry for that item with a 'NULL' initial value, and then in the 'initialize' method, instantiate the object and assign it.

我的代码的问题是我只在我的构造函数中声明了字段,但显然它们必须首先在初始化函数之外声明,由 NULL 赋值,然后在初始化函数中由相应的函数赋值争论。所以这是我的 class

的正确新版本
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)

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