我有以下代码来理解复杂的环境层:
depositor <- function() {
balance <- 0
function(amount) {
balance <<- balance + amount # assign in the parent
return(balance)
}
}
deposit <- depositor()
deposit(100)
100
deposit(32)
132
请您解释一下上述代码在环境方面的作用?
我不理解deposit <- depositor()
谢谢你们!
答案 0 :(得分:4)
理解这个例子的关键是depositor()
它会返回
depositor()
function(amount) {
balance <<- balance + amount # assign in the parent
return(balance)
}
<environment: 0x8936fb0>
这部分有点直截了当。外部函数depositor()
中的最后一个完整块是匿名函数function(amount)
的定义。所以正是这个函数成为外部函数的返回值,就像任何普通变量一样。 balance
和此匿名函数的范围仅限于外部函数,即depositor
,并且不能从外部直接访问它们。
但是,返回的匿名函数可以在父框架(全局环境)中存储和重用。
environment(fun = depositor)
# <environment: R_GlobalEnv>
environment(fun = deposit)
# <environment: 0x8a3f5a8>
parent.env( environment(fun = deposit) )
# <environment: R_GlobalEnv>
deposit <- depositor()
将此重新调整的函数存储在名为deposit的var中,并且可以通过它deposit(amountvalue)
amount
的范围仍限于内部功能。没有办法通过外部函数将amount
的值传递给它,因为它没有在其他任何地方分配。这只能通过已保存的代理deposit(100)
编辑:我重新回答了我的回答,发现我遗漏了这项练习中最有趣的部分。为什么balance
的值会从一个调用持续到另一个调用?即为什么下一次调用没有将余额值重置为0?
每次对depositor()
的新调用(不存款!)都会返回一个具有自己的父/封闭环境的函数。以下是证据:@Kota Mori在上述评论中也提出了这一点:
deposit<- depositor()
x<- depositor()
#following will have two different values
environment(deposit)
environment(x)
# and they will work independently
x(100); x(20)
deposit(100);deposit(1000)
这是closure
的关键所在,这是我无法提供的主题。对内部函数i.e., x() or deposit()
的调用不会干涉与先前调用相关联的环境,因为不会调用父函数本身,只会调用内部函数。在这种情况下,内部函数还通过<<-
赋值更新其各自封闭环境中的平衡,从而将值从一个调用持久化到下一个
另一件事可能是,为什么从函数返回的变量没有类似的封装?这是因为根据function
- the value of the last evaluated expression is returned.