我不知道这些承诺在R中做了什么
如果有人跑了
a = lapply(seq_len(2), function(n) { function() {n}})
b = lapply(seq_len(2), function(n) {n})我们可以看到
a[[1]]() # == 2
b[[1]] # == 1我理解R使用承诺的对象并在其环境中懒洋洋地计算表达式,但我不明白为什么为每个函数创建的不同环境不包含它们自己的n值。
[[1]]
function ()
{
n
}
<environment: 0x7f9b2416ad18>
[[2]]
function ()
{
n
}
<environment: 0x7f9b2416ab20>
as.list(environment(a[[1]]))
$n
[1] 2
as.list(environment(a[[2]]))
$n
[1] 2是否有可能通过lapply函数来修复语义?
lapply
function (X, FUN, ...)
{
FUN <- match.fun(FUN)
if (!is.vector(X) || is.object(X))
X <- as.list(X)
.Internal(lapply(X, FUN))
}
<bytecode: 0x7f9b25150f18>
<environment: namespace:base>PS :重订重点的问题
编辑:具体而言,是否有可能编写一个通用的“强制”参数具有统一行为的lapply2函数,如:
pl <- lapply (1:3, function(y) { force(y); function(x) pow(x,y) } )
pl <- lapply2(1:3, function(y) { function(x) pow(x,y) } )发布于 2013-08-01 13:39:17
我发现这种形式更容易理解:
f=function(n) {function() {n}}
x=1
a=f(x)
x=2
a()
[1] 2文档的关键部分是
当一个函数被调用时,参数被匹配,然后每个形式的参数被绑定到一个承诺。为该形式参数提供的表达式和调用函数的环境指针都存储在“承诺”中。
在调用a=f(x)之后,函数参数n绑定到名称为x的承诺和指向全局环境.GlobalEnv的指针。
在lapply示例中,每次都从全局环境调用匿名函数function(n) { function() {n}}。这就是为什么列表a的每个元素都具有相同的n值:它来自全局环境。我看不出通过重写lapply来改变这种行为的可能性。
发布于 2017-01-24 10:45:39
不久前,我发表了一条评论,认为R的最新版本可能会出现这种情况,但这里也有一个官方证据表明,lapply现在的行为与取自3.2.0的lapply2版本完全相同。
https://stackoverflow.com/questions/17530725
复制相似问题