tra*_*ang 5 functional-programming r lazy-evaluation
当我创建一个循环来将函数包装在列表中时,输入列表中的最后一个函数总是用于所有包装调用.
wrapper <- function(f)function()f()
fs <- list(f = function()"call f", g = function()"call g")
ws <- list()
for(n in names(fs))
ws[[n]] <- wrapper(fs[[n]])
ws$f()
[1] "call g"
Run Code Online (Sandbox Code Playgroud)
我期望"call f"在上面的代码,但它"call g"实际上返回.
谁能解释我为什么会这样?
什么是标志,或者在哪种情况下我必须强制进行评估以避免类似的情况
非常感谢你
终于我找到了自己的答案
发生这种情况的原因有两个:for循环没有自己的环境并且wrapper延迟评估其参数f。
第一个原因:for循环使用全局环境
对于后一个原因:更改wrapper为function(f){force(f); function()f()}会导致我在问题中的预期结果。
详细解释:
问题中的循环被解释为
for(n in names(fs)){
tmp <- fs[[n]]
ws[[n]] <- wrapper(tmp)
}
Run Code Online (Sandbox Code Playgroud)
因为wrapper延迟计算参数f,所以它保留f在其执行环境中,但不保留其值。相反,它会在需要时记住如何评估f。换句话说,它记住了这对(<environment: R_GlobalEnv>, "tmp")。
检查下面的代码就可以清除我所说的一切。
tmp <- f
wf <- wrapper(tmp)
tmp <- g
wf()
[1] "call g"
Run Code Online (Sandbox Code Playgroud)
但
tmp <- f
wf <- wrapper(tmp)
wf()
[1] "call f"
tmp <- g
wf()
[1] "call f"
Run Code Online (Sandbox Code Playgroud)
后一个代码"call f"在第二次调用中打印,因为f已评估并存储在wrapper的环境中,并且不需要再次评估(成为g)
| 归档时间: |
|
| 查看次数: |
97 次 |
| 最近记录: |