Max*_*m.K 60 r lazy-evaluation
我正在阅读Hadley Wickhams关于Github的书,特别是关于懒惰评估的这一部分.在那里,他举例说明了懒惰评估的后果,在有add/adders
功能的部分.让我引用一下:
在使用lapply或循环创建闭包时,[懒惰评估]很重要:
Run Code Online (Sandbox Code Playgroud)add <- function(x) { function(y) x + y } adders <- lapply(1:10, add) adders[[1]](10) adders[[10]](10)
在第一次调用其中一个加法器函数时,会对x进行延迟计算.此时,循环完成,x的最终值为10.因此,所有加法器函数都会在其输入上添加10,可能不是您想要的!手动强制评估修复了问题:
Run Code Online (Sandbox Code Playgroud)add <- function(x) { force(x) function(y) x + y } adders2 <- lapply(1:10, add) adders2[[1]](10) adders2[[10]](10)
我似乎不明白那一点,而且那里的解释很少.有人可以详细说明这个特定的例子,并解释那里发生了什么?我特别对句子感到困惑"此时,循环完成,x的最终值为10".什么循环?什么最终价值,在哪里?一定是简单的我想念,但我只是没有看到它.非常感谢提前.
jhi*_*hin 57
从R 3.2.0开始,这已不再适用!
更改日志中的相应行显示:
诸如apply函数和Reduce()之类的高阶函数现在强制它们应用的函数的参数,以便消除惰性求值和闭包中的变量捕获之间的不期望的交互.
事实上:
add <- function(x) {
function(y) x + y
}
adders <- lapply(1:10, add)
adders[[1]](10)
# [1] 11
adders[[10]](10)
# [1] 20
Run Code Online (Sandbox Code Playgroud)
Pau*_*tra 35
目标:
adders <- lapply(1:10, function(x) add(x) )
Run Code Online (Sandbox Code Playgroud)
是创建一个add
函数列表,第一个添加1到它的输入,第二个添加2,等等.懒惰的评估使R等待真正创建加法器函数,直到你真正开始调用函数.问题是在创建第一个加法器函数之后,循环x
增加lapply
,结束于值10.当你调用第一个加法器函数时,延迟评估现在构建函数,得到值x
.问题是原始x
不再等于1,而是等于lapply
循环结束时的值,即10.
因此,延迟评估会导致所有加法器函数等到lapply
循环完成后才真正构建函数.然后他们用相同的值构建他们的函数,即10. Hadley建议的解决方案是强制x
直接评估,避免惰性求值,并使用正确的x
值获得正确的函数.