4. 运行环境运行环境,是函数被调用时,产生的内存环境。运行环境是临时的,当函数运行完成后,运行环境会被自动销毁。在运行环境中的,定义的变量、对象和函数,也是动态创建的,随着内存释放而销毁。
定义一个函数g,在函数g中,有临时变量a和参数x。
> g <- function(x) {+ if (!exists("a", inherits = FALSE)) {+ a<-1+ }+ a<-a+x+ a+ }# 调用函数g> g(10)[1] 11> g(10)[1] 11调用2次函数g,运行结果都是11。我们可以看出,变量a在g函数中为临时变量,没有进行持有化,每次都是新的。
增加一些输出信息,我们再来看看,这个函数的运行情况。
> g <- function(x) {+ message("Runtime function") # 增加注释+ print(environment()) # 打印运行时环境+ if (!exists("a", inherits = FALSE)) {+ a<-1+ }+ a<-a+x+ a+ }# 调用函数g> g(10)Runtime function<environment: 0x000000000e447380>[1] 11> g(10)Runtime function<environment: 0x000000000d2fa218>[1] 11我们还是调用2次g函数,看到print(environment()) 的输出,有2次不同的环境地址 0x000000000e447380,0x000000000d2fa218。说明函数的运行时环境,是内存临时分配的。
5. 调用环境调用环境,是指函数是在哪个环境中被调用的。匿名函数通常是在定义的封闭环境中被调用。
我们定义一个嵌套的函数h,包括一个匿名函数。
> h <- function() {+ x <- 5+ function() {+ x+ }+ }# 调用函数h,把h函数内部的匿名函数赋值给r1> r1 <- h()# 在当前环境定义变量x> x <- 10# 调用函数r1> r1()[1] 5r1函数运行后的结果为5,说明r1函数获得的是匿名函数查所在的封闭环境的x值,而不是r1变量所在的当前环境的x值。
我们把代码稍后修改,在函数h中,定义2个x变量。用<<-给第二个x变量赋值,相当于给父环境空间中的x变量赋值。
> h <- function() {+ x <- 10+ x <<- 5+ function() {+ x+ }+ }# 调用函数h> r1 <- h()# 调用函数r1> r1()[1] 10# 当前空间的变量x> x[1] 5r1函数运行后的结果为10,说明r1函数获得的是匿名函数查所在的封闭环境的x值10,而不是通过<<-赋值的父环境中的x的值。 |