[英]Understanding Enclosing Environment
我有以下代码
new_counter <- function(){
ij <- 0
function(){
ij <<- ij+1
ij
}
}
counter_one <- new_counter()
counter_two <- new_counter()
counter_one()
counter_one()
从本教程 。
他们写:
计数器通过不修改其本地环境中的变量来绕过“新开始”限制。 由于更改是在不变的父(或封闭)环境中进行的,因此它们在函数调用中保留。
这就是我的想法: new_counter
函数是在.GlobalEnv
( enclosing environment
)中创建的,也是在counter_one
函数中创建的。 但是new_counter
函数的execution environment
比counter_one函数高一级。 这通常是暂时的,但这次不是因为我们有一个机箱功能。
但是,我怎么能看到“这个” 封闭的环境并且它们相距一层呢? 使用(pryr) where
和环境为全球环境提供两种功能。
编辑:他们谈论两种不同的环境:
所以对我来说这是两种不同的环境,但如果它们不同,它们可能有不同的名称! 我该怎么知道这个名字? 运用
where("new_counter")
where("counter_one")
两者都提供了全球环境,但在上面的枚举中,这必须是两个不同的。
这应该有希望澄清正在发生的事情。 请注意, new_counter
的封闭环境是全局环境,但counter_one
和counter_two
的环境是new_counter
的两个执行实例中的new_counter
。 通常,函数的封闭环境是它的词汇环境(定义它的环境),但在某些情况下,这会有所不同。
new_counter <- function(){
e <- environment()
print(e)
ij <- 0
function(){
ij <<- ij+1
ij
}
}
counter_one <- new_counter() # A
counter_two <- new_counter() # B
counter_one()
counter_one()
environment(new_counter) # global environment
environment(counter_one) # see output of A
environment(counter_two) # see output of B
这是一个更简单的示例,它显示函数可以位于一个环境中,但其封闭环境可以是不同的环境。 在这种情况下, f
在全球环境中; 然而,它的封闭环境是e
而不是全球环境。
e <- new.env()
e$x <- 1
x <- 2
f <- function() x
environment(f) <- e
f()
## [1] 1
实际上有几种环境可以考虑。 让我们在最后一个例子中为f
添加一些检测。
f <- function() {
ee <- environment()
print(ee)
x
}
e <- new.env()
e$x <- 1
x <- 2
environment(f) <- e
f() # displays ee and then the value of x which is 1
这些是环境:
f
的封闭环境是e
因为我们这样设置
词汇环境是f所处的环境。这是全球环境。 通常,词汇环境和封闭环境是相同的,但是因为我们重置f
的封闭环境,在这种情况下它们是不同的。
函数f
在运行时的执行环境。 在这种情况下,它是ee
。 当f
完成时,执行环境将被销毁,除非仍有来自外部的指针。 每次运行f
都会创建一个新的执行环境,因此每次运行f
ee
都会获取一个新值。
因此,在该示例中,每次运行f
都存在e
,全局环境和一个执行环境。
这里有一些讨论: http : //adv-r.had.co.nz/Environments.html
更新一些说明。
没有pryr
,你可以看到类似的环境:
environment(counter_one)
# <environment: 0x00000000078be648>
environment(counter_two)
# <environment: 0x00000000078bf148>
ls(env=environment(counter_two))
# [1] "ij"
counter_one()
# [1] 1
get("ij", envir = environment(counter_one))
# [1] 1
get("ij", envir = environment(counter_two))
# [1] 0
此外,您可以更改该环境中变量的值:
assign("abc", 123, envir = environment(counter_two))
ls(envir = environment(counter_one))
# [1] "ij"
ls(envir = environment(counter_two))
# [1] "abc" "ij"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.