R 中的函数环境
Function environment in R
我有下面的代码来理解复杂的环境层:
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()
谢谢大家!
理解这个例子的关键是depositor()
它将 return
depositor()
function(amount) {
balance <<- balance + amount # assign in the parent
return(balance)
}
<environment: 0x8936fb0>
这部分比较简单。外部函数 depositor()
内的最后一个完整块是匿名函数 function(amount)
的定义。所以正是这个函数变成了外部函数的 return 值,就像任何普通变量一样。 balance
和这个匿名函数的作用域都限制在外层函数,即depositor
,其中none可以直接从外部访问。
但是,这样 returned 的匿名函数可以在父框架(全局环境)中存储和重用。
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
的值在一次调用中持续存在?即,为什么下一次调用不将 balance 的值重置为 0?
每次对 depositor()
(not deposit!)的新调用都将 return 一个具有自己的 parent/enclosing 环境的函数。这是@Kota Mori 在上面的评论中也建议的proof:It:
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()
不会干扰与先前调用关联的环境,因为不会调用父函数本身,只会调用内部函数。在这种情况下,内部函数还通过 <<-
赋值更新其各自封闭环境中的余额,从而将一次调用的值保存到 next
另一件事可能是,为什么从函数 returned 的变量没有类似的外壳?这是因为根据 function
的文档 - the value of the last evaluated expression is returned.
我有下面的代码来理解复杂的环境层:
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()
谢谢大家!
理解这个例子的关键是depositor()
它将 return
depositor()
function(amount) {
balance <<- balance + amount # assign in the parent
return(balance)
}
<environment: 0x8936fb0>
这部分比较简单。外部函数 depositor()
内的最后一个完整块是匿名函数 function(amount)
的定义。所以正是这个函数变成了外部函数的 return 值,就像任何普通变量一样。 balance
和这个匿名函数的作用域都限制在外层函数,即depositor
,其中none可以直接从外部访问。
但是,这样 returned 的匿名函数可以在父框架(全局环境)中存储和重用。
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
的值在一次调用中持续存在?即,为什么下一次调用不将 balance 的值重置为 0?
每次对 depositor()
(not deposit!)的新调用都将 return 一个具有自己的 parent/enclosing 环境的函数。这是@Kota Mori 在上面的评论中也建议的proof:It:
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()
不会干扰与先前调用关联的环境,因为不会调用父函数本身,只会调用内部函数。在这种情况下,内部函数还通过 <<-
赋值更新其各自封闭环境中的余额,从而将一次调用的值保存到 next
另一件事可能是,为什么从函数 returned 的变量没有类似的外壳?这是因为根据 function
的文档 - the value of the last evaluated expression is returned.