<-
在当前环境中进行赋值。
当你在一个函数中时,R 会为你创建一个新环境。默认情况下,它包括创建它的环境中的所有内容,因此您也可以使用这些变量,但您创建的任何新内容都不会写入全局环境。
在大多数情况下<<-
,即使您在函数内部,也会分配给全局环境中已经存在的变量或在全局环境中创建变量。然而,它并不像那样简单。它的作用是检查父环境以查找具有感兴趣名称的变量。如果它在您的父环境中找不到它,它会转到父环境的父环境(在创建函数时)并在那里查找。它继续向上到全局环境,如果在全局环境中找不到它,它将在全局环境中分配变量。
这可能说明正在发生的事情。
bar <- "global"
foo <- function(){
bar <- "in foo"
baz <- function(){
bar <- "in baz - before <<-"
bar <<- "in baz - after <<-"
print(bar)
}
print(bar)
baz()
print(bar)
}
> bar
[1] "global"
> foo()
[1] "in foo"
[1] "in baz - before <<-"
[1] "in baz - after <<-"
> bar
[1] "global"
我们第一次打印 bar 我们还没有调用foo
所以它应该仍然是全局的——这是有道理的。我们第二次打印它是foo
在调用之前的内部,baz
所以“in foo”的值是有意义的。下面是我们看到<<-
实际在做什么的地方。打印的下一个值是“in baz - before <<-”,即使 print 语句出现在<<-
. 这是因为<<-
不查看当前环境(除非您在全局环境中,这种情况下的<<-
行为类似于<-
)。所以baz
bar 的值内部保持为“in baz - before <<-”。一旦我们调用baz
bar inside of 的副本,foo
就会更改为“in baz”,但我们可以看到全局bar
没有变化。bar
foo
当我们创建时,它在父环境中定义,baz
所以这是bar
它<<-
看到的第一个副本,因此是它分配给的副本。所以<<-
不仅仅是直接分配给全局环境。
<<-
很棘手,如果可以避免,我不建议使用它。如果您真的想分配给全局环境,您可以使用 assign 函数并明确告诉它您要全局分配。
现在我将其更改<<-
为分配语句,我们可以看到它有什么效果:
bar <- "global"
foo <- function(){
bar <- "in foo"
baz <- function(){
assign("bar", "in baz", envir = .GlobalEnv)
}
print(bar)
baz()
print(bar)
}
bar
#[1] "global"
foo()
#[1] "in foo"
#[1] "in foo"
bar
#[1] "in baz"
因此,foo
即使在调用baz
. 这是因为我们assign
从来没有考虑过 foo 内部的副本,bar
因为我们告诉了它在哪里看。但是,这一次全局环境中 bar 的值发生了变化,因为我们在那里显式分配。
现在您还询问了有关创建局部变量的问题,您也可以很容易地做到这一点,而无需创建函数……我们只需要使用该local
函数。
bar <- "global"
# local will create a new environment for us to play in
local({
bar <- "local"
print(bar)
})
#[1] "local"
bar
#[1] "global"