函数中给全局变量赋值
R里可以用<<-
来进行全局赋值,比如我在解Project Euler 15题时,就用了<<-
,这个最好还是不要用,用全局赋值可能会给你surprise,会给出惊喜的代码不是好代码。
当然所谓的全局和局部,都是相对的,主要看内存管理的实现方式,内存堆栈,在R里通过environment来实现,S中称之为frames。所谓的全局变量就是位于.GlobalEnv中而已。
所以如果要用<<-
来进行全局赋值的话,安全的做法是使用局部的全局变量。如果要做个类比的话,这有点像C/C++里的静态变量。
比如下面这段计算fibonacci数的函数:
fibonacci <- local({
memo <- c(1, 1, rep(NA, 20))
f <- function(x) {
if(x == 0) return(0)
if(x < 0) return(NA)
if(x > length(memo))
stop("''x'' too big for implementation")
if(!is.na(memo[x])) return(memo[x])
ans <- f(x-2) + f(x-1)
memo[x] <<- ans
ans
}
})
> fibonacci(15)
[1] 610
> get("memo", envir=environment(fibonacci))
[1] 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
[16] NA NA NA NA NA NA NA
environment是个好东西,我很惊讶于我看过的书里基本都没讲到。R的面向对象系统R5,就目前来看,是纯R实现的,用的就是S4和environment。
PS:S3面向对象就是加个class属性,通常用list来存储数据。我一直觉得,把数据存在封闭的environment里,再加个class属性,基本上就可以当成是个简易版的S4了,当然S4怎么实现,我并不清楚。