6

我已经定义了一个匿名函数列表,这些函数使用在外部范围中定义的变量。

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

funclist[[1]]('foo')

输出是:

[1] 5

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

[1] 1

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

4

2 回答 2

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
于 2013-04-25T14:21:49.427 回答
3

我对您想要的内容的阅读是在定义函数时在函数的环境中存储一个值,然后保留该值以进行内部计算。

为此,您需要一个闭包:

i <- 3
test <- local({
  i <- i
  function(x) x[i]
})
test(letters[1:5]) # returns 'c'
i <- 5
test(letters[1:5]) # still returns 'c' (i.e. i is local to the test closure)

那是你想要的吗?

于 2013-04-25T14:21:21.150 回答