学习笔记,仅供参考,有错必纠
文章目录
- R开发
- 应用R语言中的函数环境空间
- R语言的函数环境空间
- 封闭环境
- 绑定环境
- 运行环境
- 调用环境
- 函数环境空间图示
R开发
应用R语言中的函数环境空间
R语言的函数环境空间
在R语言中,变量、对象、函数都存在于环境空间中,而函数又可以有自己的环境空间,我们可以在函数内再定义变量、对象和函数,循环往复就形成了我们现在用的R语言环境系统。
一般情况下,我们可以通过new.env
去创建一个环境空间,但更多的时候,我们使用的是函数环境空间。函数环境空间,包括以下四方面的内容:
- 封闭环境,每个函数都有且只有一个封闭环境空间,指向函数定义的环境空间。
- 绑定环境,给函数指定一个名字,绑定到函数变量,如
fun1<-function() {1}
。 - 运行环境,当函数运行时,在内存中动态产生的环境空间,运行结束后,会自动销毁。
- 调用环境,是指在哪个环境中进行的方法调用,如
fun1<-function() {fun2()}
,函数fun2
在函数fun1
中被调用。
封闭环境
封闭环境是对函数空间的一个静态定义,在函数定义时指向所在的环境空间。我们在当前的环境空间定义一个函数f1,并通过environment函数来查看封闭环境:
y <- 1
f1 <- function(x) {x + y}
environment(f1) #<environment: R_GlobalEnv>
绑定环境
绑定环境就是把函数的定义和调用通过函数变量连起来。
我们新建一个环境空间e,在e的环境空间中定义一个函数g,就相当于把一个函数绑定到g变量,通过找到e环境空间中的g变量,就可以调用这个函数:
e <- new.env()
e$g <- function() {1}
#查看函数g的定义
e$g #function() {1}
#调用函数g
e$g() #1
在环境空间e中再定义一个嵌套函数:
e <- new.env()
e$f <- function() {function() {1}}
e$f # function() {function() {1}}
e$f() # function() {1}
e$f()() #1
查看函数g和f的封闭环境:
environment(e$g) #<environment: R_GlobalEnv>
environment(e$f) #<environment: R_GlobalEnv>
运行环境
运行环境是函数被调用时产生的内存环境。运行环境是临时的,当函数运行完成后,运行环境会被自动销毁。在运行环境中定义的变量、对象和函数,也是动态创建的,随着内存释放而销毁。
定义一个函数g,在函数g中,有临时变量a和参数x:
g <- function(x) {
message("Are you OK?")
print(environment())
a <- 1
a <- a + x
return(a)
}
g(10)
#输出start
Are you OK?
<environment: 0x00000000153fb488>
[1] 11
#输出end
g(10)
#输出start
Are you OK?
<environment: 0x00000000153ae1a8>
[1] 11
#输出end
可以看到,我们两次运行得到的环境地址是不同的,明函数的运行时环境,是内存临时分配的。
调用环境
调用环境是指函数是在哪个环境中被调用的。匿名函数通常是在定义的封闭环境中被调用。
h <- function() {
x <- 20
x <<- 5
function() {
x
}
}
x <- 10
r1 <- h()
r1() #20
x #5
函数环境空间图示
代码:
x<-5 # 在当前环境定义变量x
fun1<-function() { # 在当前环境定义fun1
print("fun1") # 打印fun1环境空间
print(environment())
x <- 1 # 在fun1函数环境中,定义变量x
function() {
print("funX") # 打印匿名环境空间
print(environment())
x+15 # 从一级父环境空间中,找到变量x
}
}
fun2 <- function() { # 在当前环境定义fun2
print("fun2") # 打印fun2环境空间
print(environment())
x<-2 # 在fun2函数环境中,定义变量x
fun1() #调用函数fun1
}
f2 <- fun2() # 在当前环境空间中,调用函数fun2,绑定到f2
fx <- f2() # 在当前环境空间中,调用匿名函数,并绑定到fx
fx