了解 ls() 范围和环境

问题描述 投票:0回答:1

我无法理解为什么这段 R 代码会这样工作。这是一个简单的函数:

weird_ls <- function() {
  
  some_env <- new.env()
  assign("a", value = 1, envir = some_env)
  assign("b", value = 2, envir = some_env)
  
  out <- function() {
    ls(envir = some_env)
  }
  
  return(out)
}

当我调用它时会发生以下情况:

> f <- weird_ls()
> f()

[1] "a" "b"

但是为什么会这样呢?在我的理解中,对象

f
是在全局环境中定义的函数。当我调用它时,它在自己的(新的)运行时环境中运行,并在其中执行
ls(envir = some_env)
。但是运行时环境或其父级全局环境中没有
some_env
对象。事实上,
some_env
仅在赋值期间定义
f <- weird_ls()
,但从未被函数返回。

任何人都可以帮忙解释一下吗?我怀疑我可能遗漏了范围和环境规则方面的一些内容。

r environment scoping lexical-scope
1个回答
0
投票

定义函数的环境(包括其所有内容)是函数的一部分,因此传递函数时我们也传递了该环境。函数运行时创建的框架中的对象只有在没有任何内容指向它们的情况下才会被垃圾收集。简化示例

weird_ls <- function() {

  print(environment())
  a <- 1
  function() {}

}

f <- weird_ls() # environment/frame of runtime instance of weird_ls from print
## <environment: 0x00000265e7a84238>

environment(f) # R still knows about that environment since it is part of f
## <environment: 0x00000265e7a84238>

ls(environment(f))  # the objects in that environment are still there
## [1] "a"

environment(f)$a  # we can retrieve the value of a
## [1] 1
© www.soinside.com 2019 - 2024. All rights reserved.