环境如何记住它的存在?
How does an environment remember that it exists?
拿
adder <- local({
x <- 0
function() {x <<- x+1; x}
})
或等同于
adderGen <- function(){
x <- 0
function() {x <<- x+1; x}
}
adder<-adderGen()
调用 adder()
将 return 1
再次调用它 returns 2
,依此类推。但是 adder
是如何计算的呢?我看不到任何影响全局环境的变量,那么实际用来存储这些变量的是什么?特别是在第二种情况下,您希望 adder
忘记它是在函数调用内部进行的。
每个函数都保留将其定义为函数一部分的环境。如果 f
是一个函数,那么 environment(f)
显示它。通常 adderGen
中的执行环境在退出时会被丢弃,但是因为 adderGen
传递出一个函数,其环境是 adderGen
中的执行环境,该环境作为函数的一部分保留晕倒。我们可以通过显示adderGen
中的执行环境来验证,然后验证它是否与adder
中的环境相同。 trace
函数会在adderGen
函数体的开头插入打印语句,每次adderGen
运行时都会显示执行环境。 environment(adder)
是同样的环境。
trace(adderGen, quote(print(environment())))
## [1] "adderGen"
adder <- adderGen()
## Tracing adderGen() on entry
## <environment: 0x0000000014e77780>
environment(adder)
## <environment: 0x0000000014e77780>
为了看看发生了什么,让我们定义函数如下:
adderGen <- function(){
print("Initialize")
x <- 0
function() {x <<- x+1; x}
}
当我们评估它时,我们得到:
adder <- adderGen()
# [1] "Initialize"
赋值给adder
的对象是adderGen
的内部函数(即adderGen
的输出)。请注意,adder
不再打印 "Initialize"
。
adderGen
# function(){
# print("Initialize")
# x <- 0
# a <- function() {x <<- x+1; x}
# }
adder
# function() {x <<- x+1; x}
# <environment: 0x55cd4ebd3390>
我们可以看到它也创建了一个新的调用环境,它继承了adderGen
.
环境中的变量x
ls(environment(adder))
# [1] "x"
get("x",environment(adder))
# [1] 0
第一次执行adder
时,它使用x
的继承值,即0,将x
重新定义为全局变量(在其调用环境中)。而这个全局变量就是它在下一次执行中使用的那个。因为 x <-0
不是函数 adder
的一部分,所以当 adder
被执行时,变量 x
没有被初始化为 0 并且它将 [= 的当前值递增 1 20=].
adder()
# [1] 1
拿
adder <- local({
x <- 0
function() {x <<- x+1; x}
})
或等同于
adderGen <- function(){
x <- 0
function() {x <<- x+1; x}
}
adder<-adderGen()
调用 adder()
将 return 1
再次调用它 returns 2
,依此类推。但是 adder
是如何计算的呢?我看不到任何影响全局环境的变量,那么实际用来存储这些变量的是什么?特别是在第二种情况下,您希望 adder
忘记它是在函数调用内部进行的。
每个函数都保留将其定义为函数一部分的环境。如果 f
是一个函数,那么 environment(f)
显示它。通常 adderGen
中的执行环境在退出时会被丢弃,但是因为 adderGen
传递出一个函数,其环境是 adderGen
中的执行环境,该环境作为函数的一部分保留晕倒。我们可以通过显示adderGen
中的执行环境来验证,然后验证它是否与adder
中的环境相同。 trace
函数会在adderGen
函数体的开头插入打印语句,每次adderGen
运行时都会显示执行环境。 environment(adder)
是同样的环境。
trace(adderGen, quote(print(environment())))
## [1] "adderGen"
adder <- adderGen()
## Tracing adderGen() on entry
## <environment: 0x0000000014e77780>
environment(adder)
## <environment: 0x0000000014e77780>
为了看看发生了什么,让我们定义函数如下:
adderGen <- function(){
print("Initialize")
x <- 0
function() {x <<- x+1; x}
}
当我们评估它时,我们得到:
adder <- adderGen()
# [1] "Initialize"
赋值给adder
的对象是adderGen
的内部函数(即adderGen
的输出)。请注意,adder
不再打印 "Initialize"
。
adderGen
# function(){
# print("Initialize")
# x <- 0
# a <- function() {x <<- x+1; x}
# }
adder
# function() {x <<- x+1; x}
# <environment: 0x55cd4ebd3390>
我们可以看到它也创建了一个新的调用环境,它继承了adderGen
.
x
ls(environment(adder))
# [1] "x"
get("x",environment(adder))
# [1] 0
第一次执行adder
时,它使用x
的继承值,即0,将x
重新定义为全局变量(在其调用环境中)。而这个全局变量就是它在下一次执行中使用的那个。因为 x <-0
不是函数 adder
的一部分,所以当 adder
被执行时,变量 x
没有被初始化为 0 并且它将 [= 的当前值递增 1 20=].
adder()
# [1] 1