我有以下代码
new_counter <- function(){
ij <- 0
function(){
ij <<- ij+1
ij
}
}
counter_one <- new_counter()
counter_two <- new_counter()
counter_one()
counter_one()
来自tutorial。
他们写道:
计数器通过不修改来绕过“新开始”限制 当地环境中的变量。由于进行了更改 不变的父(或封闭)环境,它们被保留 跨职能电话。
我认为这是:new_counter
函数是在.GlobalEnv
(enclosing environment
)以及counter_one
函数中创建的。但execution environment
new_counter
函数比counter_one函数高一级。这通常是暂时的,但这次不是因为我们有一个机箱功能。
但我怎么能看到'this'封闭环境并且它们相隔一层?使用(pryr)where
和环境为全局环境提供两种功能。
编辑: 他们谈论两种不同的环境:
所以对我来说,这是两种不同的环境,但如果它们不同,它们可能有不同的名称!我该怎么知道这个名字?使用
where("new_counter")
where("counter_one")
既可以提供全球环境,但查看上面的枚举,必须是两个不同的。
答案 0 :(得分:2)
这应该有希望澄清正在发生的事情。请注意,new_counter
的封闭环境是全局环境,但counter_one
和counter_two
的环境是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
时,都会创建一个新的执行环境,以便ee
每次运行f
时都会获取一个新值。
因此,在此示例中,每次e
运行时都会有f
,全局环境和一个执行环境。
这里有一些讨论:http://adv-r.had.co.nz/Environments.html
更新一些澄清。
答案 1 :(得分:1)
如果没有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"