r - 是否可以在 R 中通过一次调用创建有状态函数?

标签 r function r-environment

我知道我可以使用工厂函数 adder_maker 创建一个有状态函数 adder,如下所示:

adder_maker <- function() {x <- 0; function() {x <<- x+1; x}}
adder1 <- adder_maker()
adder1()
adder1()
environment(adder1)

该函数按预期递增并位于其自己的封闭环境中。

但是,如果我不想将工厂函数存储在中间变量中,那么内部函数最终会出现在全局环境中。

adder2 <- function() {x <- 0; function() {x <<- x+1; x}}()
adder2()
adder2()
environment(adder2)
  1. 为什么 adder2 不与其匿名父级的环境相关联?
  2. 如果 adder2 存在于全局环境中,为什么它返回 1(而不是 Error: object 'x' not found,当尝试计算内部赋值的 RHS 时,x+ 1)?
  3. 是否有任何其他聪明的方法来创建一个行为类似于 adder1 的函数,而无需为父函数分配变量?

最佳答案

关于 1 和 2):

这与评估顺序有关。您的代码是:

adder2 <- function() {x <- 0; function() {x <<- x+1; x}}()

这里首先执行的是R表达式{x <- 0; function() {x <<- x+1; x}} .您可能知道 R 中表达式的值是表达式中的最后一个值。因此,在这种情况下,表达式的计算结果为匿名函数(它位于定义了 x <- 0 的环境中):

> {x <- 0; function() {x <<- x+1; x}}
function() {x <<- x+1; x}

在下一步中,将调用此中间函数(而不是您预期的整个函数!)此中间代码的结果当然是 1。所以剩下的有效内容是:

adder2 <- function() 1

这解释了行为,以及为什么它与括号一起工作,如评论中所述。

关于 3):

您正在寻找函数 local :

> adder2 <- local({x <- 0; function() {x <<- x+1; x}})
> adder2()
[1] 1
> adder2()
[1] 2

关于r - 是否可以在 R 中通过一次调用创建有状态函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52089121/

相关文章:

r - 使 ggvis 图具有 Shiny 的 react 性

r - 在不同环境中调用时,部分粘合功能不起作用

r - 有因素时的多重共线性检验

r - kableExtra:动态add_header_above标签

function - F# 生成随机数时的函数简洁性

sql - 获取定义相等时间段的记录的总和/平均值

function - 如何用细化来包装一个函数,这样就不需要细化了?

r - 如何重新排序搜索路径?

r - 参数 'pattern' 的长度 > 1 并且仅使用第一个元素 - GSUB()