R语言Lazy Evaluation(延迟求值)失效问题咨询
为什么R延迟求值示例结果和《Advanced R》不一致?
别慌,你遇到的不是延迟求值失效,而是R版本更新带来的行为变更!
问题根源
《Advanced R》里的示例是基于旧版R(3.2.0之前)的行为:当时lapply的循环变量是在一个共享环境中创建的,所有闭包都会捕获这个共享变量的最终值。所以当你运行完lapply(1:10, add)后,所有adders里的函数引用的都是最后一次迭代的x=10,自然adders[[1]](10)会得到20。
但在R 3.2.0及以后的版本,官方修改了lapply的实现:每次迭代都会创建独立的环境,每个闭包捕获的是当前迭代的x值。所以adders[[1]]捕获的是x=1,加10就得到11,这才是现在R的默认(更符合直觉的)行为。
验证与重现旧行为
如果想亲眼看看旧版的效果,可以用for循环模拟旧版lapply的共享环境逻辑:
add <- function(x) { function(y) x+y } adders_old <- vector("list", 10) # for循环的变量在父环境中,所有闭包共享同一个x for (i in 1:10) { adders_old[[i]] <- add(i) } adders_old[[1]](10) # 输出20,和书里一致 adders_old[[10]](10) # 输出20
总结
你的R版本是较新的,延迟求值特性并没有失效——只是现在的lapply行为更合理了。书里的内容是针对旧版R的,不用怀疑自己的操作哦~
内容的提问来源于stack exchange,提问作者Belinda
相关产品推荐
相关产品推荐

