问题描述
我在循环中定义函数并尝试强制对循环变量求值,而不必携带私有环境.
I'm defining functions in a loop and trying to force evaluation of a loop variable without having to carry around a private environment.
示例:一组函数 handlers$h1
, handlers$h2
, ..., handlers$h6
只是通过1, 2, ..., 6 到另一个像这样的函数:
Example: a set of functions handlers$h1
, handlers$h2
, ..., handlers$h6
that just pass through the 1, 2, ..., 6 to another function like so:
handlers <- list()
for (i in 1:6) {
handlers[[paste0('h', i)]] <- function () {
message(i) # <-- example
}
}
所以 handlers$h1()
应该是消息 1,handlers$h2()
应该是消息 2,...
So handlers$h1()
should message 1, handlers$h2()
should message 2, ...
相反,所有函数都返回6
,即i
的当前值.
Instead, all of the functions return 6
, the current value of i
.
为了解决这个问题,我可以使用 在这个问题中指定的闭包
To get around this I can use a closure as specified in this question
msg <- function(i) {
force(i)
function () { message(i) }
}
for (i in 1:6) {
handlers[[paste0('h', i)]] <- msg(i)
}
现在每个函数都按预期工作,但是每个函数都必须携带自己的环境:
Now each function works as expected, but each function has to carry around its own environment:
handlers$h1
# function () { message(i) }
# <environment: 0x9342b80>
如何才能使 handlers$h1
打印 function () { message(1) }
,即评估 i
并将其直接替换到定义中,从而消除对环境的需求?
How can I make it so that handlers$h1
prints function () { message(1) }
, i.e. evaluates the i
and substitutes it directly into the definition, removing the need for the environment?
我能想到的唯一方法是:
The only ways I can think of are to:
- 使用
eval
(我不喜欢这样做); - 手工写出每个定义,直接替换 1-6(在这种情况下,只有 6 个函数,但通常不可扩展)
推荐答案
以下是一些使用 body
你可以使用 bquote
handlers <- list()
for (i in 1:6) {
handlers[[paste0('h', i)]] <- function () {}
body( handlers[[paste0('h', i)]]) <- bquote(message(.(i)))
}
handlers$h1
## function ()
## message(1L)
或替换
for (i in 1:6) {
handlers[[paste0('h', i)]] <- function () {}
body( handlers[[paste0('h', i)]]) <- substitute(message(i), list(i=i))
}
这篇关于R 范围:在没有本地环境的函数中强制变量替换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!