繁体   English   中英

了解封闭环境

[英]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函数是在.GlobalEnvenclosing environment )中创建的,也是在counter_one函数中创建的。 但是new_counter函数的execution environment比counter_one函数高一级。 这通常是暂时的,但这次不是因为我们有一个机箱功能。

但是,我怎么能看到“这个” 封闭的环境并且它们相距一层呢? 使用(pryr) where环境为全球环境提供两种功能。

编辑:他们谈论两种不同的环境:

  1. '在当地环境'
  2. '在一个没有联系的父母环境中'

所以对我来说这是两种不同的环境,但如果它们不同,它们可能有不同的名称! 我该怎么知道这个名字? 运用

where("new_counter")
where("counter_one")

两者都提供了全球环境,但在上面的枚举中,这必须是两个不同的。

这应该有希望澄清正在发生的事情。 请注意, new_counter的封闭环境是全局环境,但counter_onecounter_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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM