2016-08-11 100 views
1

我已在从这个tutorial下面的代码了解内附环境

new_counter <- function(){ 
    ij <- 0 
    function(){ 
    ij <<- ij+1 
    ij 
    } 
} 

counter_one <- new_counter() 
counter_two <- new_counter() 

counter_one() 
counter_one() 

他们写道:

计数器拿到围绕“新的开始”限制在当地环境不修改 变量。由于修改是在 不变的父(或封闭)环境中进行的,因此跨功能调用将它们保留为 。

这就是我的想法是怎么回事:在.GlobalEnvenclosing environment),以及该counter_one功能,创建new_counter功能。但是函数的execution environment函数比counter_one函数高一级。这通常是暂时的,但这次不是因为我们有一个机箱功能。

但是,我怎样才能看到'这'封闭环境,他们是一个层面呢?使用(pryr)where环境为这两种功能提供全球环境。

编辑: 他们谈论两种不同的环境: '在unchainging父环境'

所以对我来说

  1. '在theire当地环境'
  2. 这是两个不同的环境但如果他们不同,他们可能会有不同的名字!我怎样才能找到名字?使用

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

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

+0

我不完全清楚你在问什么,你可以尝试解释更多/不同? – nrussell

+0

我编辑了我的问题,并希望它更容易理解。 – ruedi

+1

“使用环境'为这两种功能提供全球环境。” - 不,绝对不会。你会得到不同的环境。 –

回答

2

这样应该可以澄清所发生的事情。请注意,new_counter的封闭环境是全局环境,但counter_onecounter_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时,都会创建一个新的执行环境,因此每次运行f时,ee都会产生一个新值。

因此,在该示例中,存在e,全球环境和每个f运行时一个执行环境。

有一些讨论在这里:http://adv-r.had.co.nz/Environments.html

更新一些澄清。

+0

这是一个很好的答案!谢谢你! – ruedi

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" 
+0

啊好的。 回答我的问题。谢谢 – ruedi