我在循环中定义函数,并试图强制评估循环变量,而不必携带私有环境。
示例:一组函数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个函数,但通常不能扩展)可以很好地写出来
最佳答案
以下是一些使用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)
或
substitute
for (i in 1:6) {
handlers[[paste0('h', i)]] <- function () {}
body( handlers[[paste0('h', i)]]) <- substitute(message(i), list(i=i))
}