所以我遇到了这个与不同环境中存在的变量有关的问题,这让我很困惑,因为它不符合我对函数如何查找各种对象的理解。
我的玩具示例非常简单:我有一个函数foo
接受一个参数j
。 foo
生活在lapply
循环函数内,并带有参数' i'。现在,i
显然存在于lapply
环境中(而不是全局环境中)。在lapply函数foo
内调用时,很难找到i
并抛出错误:
foo <- function(j){
message('foo env: exists(j) ', exists('j'))
message('foo env: exists(i) ', exists('i'))
i
}
env.g <- environment()
invisible(lapply(1, FUN = function(i){
message('global env: exists(i) ', exists('i', envir = env.g))
message('lapply env: exists(i) ', exists('i'))
message(' ')
j <- i + 1
foo(j)
}
))
#global env: exists(i) FALSE
#lapply env: exists(i) TRUE
#foo env: exists(j) TRUE
#foo env: exists(i) FALSE
#Error in foo(j) : object 'i' not found
另一方面,当i
存在于全球环境中时,foo
就可以了:
i <- 10
foo()
#foo env: exists(j) TRUE
#foo env: exists(i) TRUE
#[1] 10
所以我之前的理解是,如果某个函数在自己的环境中没有看到变量,那么它将进入下一个变量(在我的第一个示例中为lapply
,在第二个示例中为全局变量) ,直到它找到它。但是,它显然没有进入上面lapply
的外循环......为什么?
答案 0 :(得分:2)
我认为这是因为函数foo()
是在定义函数的环境中进行评估的。在您的示例中,foo()
在全局环境中定义,因此i
不在范围内。如果您在匿名函数中定义foo()
,则i
似乎正确评估。
env.g <- environment()
invisible(lapply(1, FUN = function(i){
message('global env: exists(i) ', exists('i', envir = env.g))
message('lapply env: exists(i) ', exists('i'))
message(' ')
j <- i + 1
foo <- function(j){
message('foo env: exists(j) ', exists('j'))
message('foo env: exists(i) ', exists('i'))
i
}
foo(j)
}
))
#global env: exists(i) FALSE
#lapply env: exists(i) TRUE
#foo env: exists(j) TRUE
#foo env: exists(i) TRUE
答案 1 :(得分:1)
有4种类型的环境与功能相关联。
当你跑步时:
rm(i)
lapply(1, foo)
甚至:
rm(i)
lapply(1, function(x) {
i <- 42
foo(x)
})
情况是:
lapply
:
附上env:namespace:base
绑定环境:package:base
执行环境:动态创建,并附在.GlobalEnv
致电环境:.GlobalEnv
和foo
:
附上(定义的地方):.GlobalEnv
绑定(名称foo
所在的位置):.GlobalEnv
执行(包含在Calling env中):动态创建并封闭......我甚至不确定在哪里,但是当进入封闭环境链时,应该有执行环境lapply
致电:同样,不太确定......但这不重要
但:
(可能)与直觉相反,通过上升调用堆栈找不到变量&#34; AKA 动态范围 (即:foo
的exec env,(然后可能是某些中间环境),然后执行lapply
的env(其中)我们会找到i <- 42
),然后是.GlobalEnv
),但直接在foo
AKA 词汇范围 的封闭环境中,然后其封闭环境的链条绕过lapply
的执行环境,因此找不到i
,即使它刚刚在上面明确声明......