如何在R函数内部本地存储变量以实现信息累计功能?
解决R语言函数累计值且不暴露状态变量的问题
你的问题核心在于:原函数里的x是局部变量,每次调用函数时都会创建一个全新的函数环境,exists('x')检查的是这个临时的局部环境——第一次调用时没有x,就初始化0再加2;调用结束后这个局部环境被销毁,x也就消失了。第二次调用时又重复这个过程,所以每次返回都是2。
要实现一个能累计值、同时状态变量不暴露在外部的函数,最优雅的方式是用闭包(Closure)——它能让函数携带自己的私有状态,这个状态存储在闭包的专属环境中,外部无法直接访问。
解决方案代码
# 先创建一个"工厂函数",用来生成带私有状态的累计函数 create_accumulator <- function() { # 这个变量存储在闭包环境中,外部无法直接访问 private_counter <- 0 # 返回一个内部函数,它会记住工厂函数的环境 function(number.info) { # 使用<<-修改上层环境(工厂函数的环境)中的计数器 private_counter <<- private_counter + number.info return(private_counter) } } # 生成你的累计函数实例 testing <- create_accumulator()
测试效果
调用这个函数试试,就能看到累计效果了:
testing(2) # 返回 2 testing(2) # 返回 4 testing(3) # 返回 7
原理说明
create_accumulator运行时,会创建一个包含private_counter的专属环境,然后返回内部函数。- 每次调用
testing时,内部函数会找到并修改这个专属环境里的private_counter,既不会污染全局环境,也不会在每次调用时重置变量。 - 这个
private_counter完全是私有的,你在全局环境里输入private_counter会报错,因为它不存在于全局环境中。
为什么不用全局变量?
如果你直接用<<-在原函数里修改全局变量x,虽然也能累计,但会污染全局环境,容易和其他变量冲突。闭包的方式既实现了状态保留,又保证了变量的私有性,是更安全、更规范的做法。
内容的提问来源于stack exchange,提问作者Hector Haffenden
相关产品推荐
相关产品推荐

