【发布时间】:2013-03-26 01:18:43
【问题描述】:
我在循环中定义函数并尝试强制评估循环变量,而不必携带私有环境。
示例:一组函数handlers$h1、handlers$h2、...、handlers$h6,它们只是通过 1、2、...、6 到另一个函数,如下所示:
handlers <- list()
for (i in 1:6) {
handlers[[paste0('h', i)]] <- function () {
message(i) # <-- example
}
}
所以handlers$h1() 应该是消息 1,handlers$h2() 应该是消息 2,...
相反,所有函数都返回6,即i 的当前值。
为了解决这个问题,我可以使用 specified in this question 的闭包
msg <- function(i) {
force(i)
function () { message(i) }
}
for (i in 1:6) {
handlers[[paste0('h', i)]] <- msg(i)
}
现在每个函数都按预期工作,但是每个函数都必须携带自己的环境:
handlers$h1
# function () { message(i) }
# <environment: 0x9342b80>
如何使handlers$h1 打印function () { message(1) },即评估i 并将其直接替换到定义中,从而消除对环境的需求?
我能想到的唯一方法是:
- 使用
eval(我不想这样做); - 用直接替换的 1-6 手动写出每个定义(在这种情况下很好,只有 6 个函数,但通常不可扩展)
【问题讨论】:
-
R 中的每个函数都有一个关联的环境:你为什么担心它?
-
另外,你不能通过使用闭包来绕过它(你已经这样做了),你可以通过使用
force来绕过它。