2. 环境空间的特征上面中提到环境空间有一些特征,下面我们分别介绍一下。
2.1 每个环境空间中的对象名字要唯一
在当前环境空间中定义变量名x,并对x进行操作。
# 定义变量x> x<-10;x[1] 10# 查看x地址> address(x)[1] "0x2874068"# 对x改变赋值> x<-11;x[1] 11# 查看x地址> address(x)[1] "0x28744c8"这样我们可以看到,x变量在每次赋值的时候,内存地址都会发生改变,但是x的名字还是x。
在不同的环境空间中,再定义一个变量x。
# 创建环境空间e1> e1<-new.env()# 在e1中定义变量x> e1$x<-20# 输出x> x;e1$x[1] 12[1] 20在不同的环境空间中,可以有同名的变量名字。
2.2 环境空间变量的赋值
如果把e1环境空间变量,赋值给另一个变量f,再修改其环境内部变量,会是什么结果呢?
# 把e1赋值给f> f <- e1# 修改e1中a变量的值> e1$a <- 1111# 查看f环境空间的a值> f$a[1] 1111# 比较f环境和e1环境,是相等的> identical(f,e1)[1] TRUE# 查看e1和f的环境地址,是完全相同的> e1<environment: 0x3e28948>> f<environment: 0x3e28948>所以,环境空间的赋值,是一种引入的传递,而不是新创建一个环境空间。
2.3 定义更上层的环境空间
空环境是最顶层的环境空间,然后是base包的环境空间,我们可以尝试创建一个靠近顶层的环境空间,让父环境空间是base包的环境空间。
# 创建e2环境,以base为父环境> e2 <- new.env(parent = baseenv())> e2<environment: 0x37cab18># 查看e2环境的父环境列表> parent.call(e2)<environment: 0x37cab18><environment: base><environment: R_EmptyEnv>这样e2环境空间就位于了环境空间中的第三层。
2.4 子环境空间会继承父环境空间的变量
在当前环境中,定义一个变量x, 子环境e1中,对x重新赋值。
# 在当前环境,定义变量x> x<-1:5# 新建环境空间e1> e1 <- new.env()# e1环境空间中定义变量x> e1$x<-1# 在e1环境空间中定义函数,并对父环境空间的x变量重新赋值> e1$fun<-function(y){+ print('e1::fun')+ x<<-y+ }# 运行e1环境空间中的函数,将x赋值为50> e1$fun(50)[1] "e1::fun"# 当前环境x变量被修改> x[1] 50# e1环境x变量没有变化> e1$x[1] 1这样我们就可以利用 <<- 赋值符号,来修改父环境中的变量。 |