这是对efficiently move environment from inside function to global environment的答案的后续跟踪,其中指出如果希望使用该内容,则必须返回对函数内部创建的环境的引用。环境
如果我们不返回引用,新创建的环境是否仍然存在,如果是这样,那么如何跟踪这样的环境,访问其内容还是删除它?
答案 0 :(得分:4)
当然,如果它被分配到功能评估环境之外的某个符号(就像在OP的示例中那样),则环境将继续存在。从这个意义上讲,环境就像任何其他命名的R对象一样。 (closures可以保留未分配环境的事实意味着环境有时会持续存在于其他类型的对象不会发生的地方,但这并不是这里发生的事情。)
## OP's example function
funfun <- function(inc = 1){
dataEnv <- new.env()
dataEnv$d1 <- 1 + inc
dataEnv$d2 <- 2 + inc
dataEnv$d3 <- 2 + inc
assign('dataEnv', dataEnv, envir = globalenv()) ## Assignment to .GlobalEnv
}
funfun()
ls(env=.GlobalEnv)
# [1] "dataEnv" "funfun"
## It's easy to find environments assigned to a symbol in another environment,
## if you know which environment to look in.
Filter(isTRUE, eapply(.GlobalEnv, is.environment))
# $dataEnv
# [1] TRUE
在OP的示例中,它相对容易追踪,因为环境已分配给.GlobalEnv
中的符号。但是,一般而言,(并且,就像任何其他R对象一样),例如,如果将其分配给列表中的元素或更复杂的结构,则很难跟踪。
(顺便说一下,这就是为什么在R和其他更纯粹的函数式语言中通常不鼓励非本地赋值的原因。当函数只返回一个值时,该值只通过显式赋值赋给符号(如{{1执行代码的效果变得更容易推理和预测。更少的惊喜会带来更好的代码!)