【问题标题】:Global variable and scope - R全局变量和范围 - R
【发布时间】:2015-04-24 14:22:28
【问题描述】:

我不明白为什么 R 中的全局范围列表不能在函数内进行如下修改:

global <<- list()

f <- function(x) {
  global[[x]] <- "blah"
}

f(1)
f(2)
print(global)

输出是

list()

但是,我期待输出:

[[1]]
[1] "blah"

[[2]]
[1] "blah"

这是为什么?我是否必须将列表的每个元素也声明为全局元素?

对于在函数块之外声明的局部范围变量似乎也是如此。

谢谢!

【问题讨论】:

  • &lt;&lt;- 应该在你的函数中

标签: r function scope global-variables


【解决方案1】:

我相信您对&lt;&lt;- 的实际作用感到有些困惑。来自help("&lt;&lt;-")

> 运算符通常只用在函数中,并且 导致通过父环境搜索现有的 被赋值的变量的定义。如果找到这样的变量 (并且它的绑定没有被锁定)然后它的值被重新定义,否则 分配发生在全局环境中。

因此应该很清楚,&lt;&lt;- 在任何地方运行时都不会创建“全局变量”。事实上,这根本不是 R 的工作原理。

相反,&lt;&lt;- 执行一种“全局赋值”,允许您修改当前范围之外的变量。

它是更精确的assign() 的一种粗略版本。通常不鼓励使用这两种工具,因为它们往往会破坏 R 使用的函数式编程范式(即没有副作用)。与其他任何东西一样,它们有其用途,但通常不适用于常规变量处理。

【讨论】:

    【解决方案2】:

    基本上,由于您使用的是“

    这可以通过添加第二个函数 g() 来看到,它会在 f() 中打印出之前更改“global”的值,但这次使用“

    global <<- list()
    
    f <- function(x) {
      global[[x]] <- "blah"
      g(x)
      global
    }
    
    g <- function(x){
      global[[x]] <<- "newblah"
    }
    
    
    f(1)  #prints 'blah', despite the fact the g(x) has already updated the value
    
    global  #prints 'newblah'
    

    如果 f(x) 仍然引用“global”的全局副本,它将打印在 g(x) 中分配的“newblah”。相反,它将 f(x) 中分配的值打印到 'global' 的本地范围副本。

    但是,在任何函数之外打印 'global' 表明 g(x) 实际上确实更新了 'global' 的全局副本的值。

    现在,如果将 g(x) 移动到 f(x) 中,则 f(x) 现在是 g(x) 的父级。在这种情况下,“

    global <<- list()
    
    f <- function(x) {
      global[[x]] <- "blah"
    
      g <- function(x){
        global[[x]] <<- "newblah"
      }
    
      g(x)
      global
    }
    
    
    
    f(1) #prints 'newblah'
    
    global #empty
    

    【讨论】:

      猜你喜欢
      • 2013-05-26
      • 2010-10-07
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 2017-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多