功能操作员和环境

时间:2017-10-03 17:48:58

标签: r functional-programming

好的堆叠,

我一直在阅读Advanced R并且确实发现它很有帮助。我在一个我不太了解R在这个例子中的行为的地方:

$1

所以这里的想法是我们要在函数的每第n次迭代中显示一个句点。我不明白的是,通过在功能中多次调用dot_every <- function(n, f) { i <- 1 function(...) { if (i %% n == 0) cat(".") i <<- i + 1 f(...) } } 来维持i的价值。我了解dot_every在搜索名为<<-的内容的环境中向上移动,然后替换为i。我会想到这样的事情:

i+1

会在x <- lapply(1:20, dot_every(10, runif))中为每次迭代垃圾收集i,因此永远不会增加它。我的直觉是它会像这样工作:

lapply

似乎在调用for(i in 1:20){ dot_every(10, runif)(i) } ,垃圾收集dot_every,因此没有显示任何内容。在这种情况下,使用功能与for循环有什么不同?

感谢您的帮助!

1 个答案:

答案 0 :(得分:3)

在第一种情况下(使用lapply),您只调用dot_every()一次,然后对1:20中的每个元素使用结果函数。在第二种情况下,您在循环的每次传递中调用dot_every(),然后仅使用结果函数一次。要查看此内容,请插入以下行:

cat("!")

作为dot_every()定义的第一行。然后:

> x <- lapply(1:20, dot_every(10, runif))
!..

> for(i in 1:20) dot_every(10,runif)(i)
!!!!!!!!!!!!!!!!!!!!