全局变量和范围 - R.

时间:2015-04-24 14:22:29

标签: r function scope global-variables

我不明白为什么R中的全局范围列表无法在函数内修改,如下所示:

global <<- list()

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

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

输出

list()

但是,我期待输出:

[[1]]
[1] "blah"

[[2]]
[1] "blah"

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

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

谢谢!

2 个答案:

答案 0 :(得分:3)

我相信你对Map实际做的事情感到有点困惑。来自<<-

  

运营商&lt;&lt; - & - &gt;&gt;通常只用于函数,和   导致搜索通过父环境进行搜索   被分配的变量的定义。如果找到这样的变量   (并且它的绑定没有被锁定)然后重新定义它的值,否则   任务发生在全球环境中。

因此,应该清楚help("<<-")无论在何处运行都不会创建“全局变量”。实际上,这根本不是R的工作方式。

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

这是更精确<<-的粗略版本。通常不鼓励使用这两种工具,因为它们倾向于破坏R使用的功能编程范例(即没有副作用)。与其他任何东西一样,它们都有它们的用途,但通常不用于常规变量处理。

答案 1 :(得分:2)

基本上,由于您使用的是“&lt; - ”赋值,因此该函数正在创建“全局”变量的副本,以便在函数范围内使用。

这可以通过添加第二个函数g()来看出,该函数在用f()打印之前改变'global'的值,但这次使用“&lt;&lt;&lt; - ”赋值。 f()中的第一行为f(x)创建本地范围的'global'副本,然后使用g(x)更新'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'全局副本的值。

现在,如果你在f(x)中移动g(x),那么f(x)现在是g(x)的父级。在这种情况下,“&lt;&lt; - ”指定在f(x)范围内的'global'的值。所以'global'的全局副本仍然是空的,但是如果你在f()的范围内打印出'global',你会得到更新的值。

global <<- list()

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

  g <- function(x){
    global[[x]] <<- "newblah"
  }

  g(x)
  global
}



f(1) #prints 'newblah'

global #empty