R匿名函数:按值捕获变量

use*_*797 5 lambda r anonymous-function

我已经定义了一个匿名函数列表,它使用在外部作用域中定义的变量.

funclist <- list()
for(i in 1:5)
{
  funclist[[i]] <- function(x) print(i)
}

funclist[[1]]('foo')
Run Code Online (Sandbox Code Playgroud)

输出是:

[1] 5
Run Code Online (Sandbox Code Playgroud)

似乎是通过引用捕获的.我希望它被值捕获,即输出应该是

[1] 1
Run Code Online (Sandbox Code Playgroud)

有没有办法让R 通过值而不是通过引用来捕获i

Jam*_*mes 6

当您运行for循环时,这将在运行循环的环境中创建变量,并且循环中创建的函数也将从此环境运行.因此,每当您运行以这种方式创建的函数使用循环中的索引值时,它们只能访问最终值,并且只有该变量仍然存在(尝试rm(i)并尝试使列表中的某个函数变得有趣) .

您需要做的是将索引值绑定到自己环境中的函数.lapply会自动为你做这件事.然而,有一个懒惰的评估陷阱.你要做的还是在创建匿名函数之前force的评估i:

funclist <- lapply(1:5, function(i) {force(i); function(x) print(i)})
funclist[[1]]('foo')
[1] 1
funclist[[5]]('foo')
[1] 5
Run Code Online (Sandbox Code Playgroud)