R: 如何理解变量和环境的Lexical Scoping Rule
来源:互联网 发布:淘宝品质保证险是什么 编辑:程序博客网 时间:2024/06/18 15:52
非IT出身,看到Scoping Rule神马的是非常头疼的,尤其是需要涉及到Function的嵌套的时候,很容易将不同environment种的变量弄混淆,还是自己动手实践一下比较好。
在一个Function中,对一个变量的lexical scoping rule的检索次序是,先检查本Function中的environment,如果能找到该变量,则返回该变量,如果不能,则检索这个Function被创建(不是被调用)的Environment,以此类推,一直到检索Global Environment。
写了2段code,在写code之前,先提出两个问题:
1. a和全局环境各存在一个环境e,当a调用b时,b中的e$x, e$y和e$z如何检索?
2. 全局环境变量的赋值符号 "<<-"如何发挥作用?
第一段:b函数在a函数外创建,a函数及global env.各创建一个环境变量e
# Chunk 1:
> a <- function(x){
> e <- new.env()
> e$x <- 111
>
> c <- b(x)
> return(c(c, e$y, e$z))
> }
>
> b <- function(x){
> x <- e$x + x
> e$y <- x + 1
> e$z <<- x + 2
> return(x)
> }
>
> e <- new.env()
> e$x <- 222
> a(5)
> e$x <- 111
>
> c <- b(x)
> return(c(c, e$y, e$z))
> }
>
> b <- function(x){
> x <- e$x + x
> e$y <- x + 1
> e$z <<- x + 2
> return(x)
> }
>
> e <- new.env()
> e$x <- 222
> a(5)
# [1] 227
> e$y
# [1] 228
> e$z
# [1] 229
运行完这一段,我们可以回答上面提出的两个问题:
1. a 中的环境e及其中的变量x (=111)被忽略,Function b调用的e环境,首先在b里进行检索,无果,然后进入b被创建的环境(即与Function a,和另一个Environment e被同时创建的环境,暂且理解为Global Env.)进行检索,这里的e中,x = 222,所以a(5)返回的并不是111+5 而是 222+5,另a中的e$y, e$z均为NULL.
2. b函数中的x = e$x + x = 227,与此同时将更新后的x,加上1和2,分别赋值给e环境中的y和z,e的检索方式和答案1中的逻辑一致,均赋值给Global Env.中的e环境,不管赋值符是什么形式的,注意这里只有两层环境,无法做更多的检验,所以我们要进一步检查“<<-”的作用。
rm(list = ls())之后(清空刚才创建的所有环境和变量),再来看第二段code:
b函数在a函数内创建,a函数及global env.各创建一个环境变量e
# Chunk 2:
> a <- function(x){
> e <- new.env()
> e$x <- 111
>
> b <- function(x){
> x <- e$x + x
> e$y <- x + 1
> e$z <<- x + 2
> return(x)
> }
>
> c <- b(x)
> return(c(c, e$y, e$z))
> }
>
> e <- new.env()
> e$x <- 222
> e <- new.env()
> e$x <- 111
>
> b <- function(x){
> x <- e$x + x
> e$y <- x + 1
> e$z <<- x + 2
> return(x)
> }
>
> c <- b(x)
> return(c(c, e$y, e$z))
> }
>
> e <- new.env()
> e$x <- 222
>
> a(5)
# [1] 116 117 118
> e$z
# NULL
接下来回答同样的问题:
1. b函数创建的环境中同时创建了一个环境变量e,尽管a创建的环境中也有一个e,但是b函数里调用的e$x显然来自前者。所以这段code中a(5)可以返回3个数值,因为这三个数的环境e均来自于a函数的环境。
2. 在global env.中调用e$z并没有返回118,而是返回的NULL,说明"<<-"赋值符并不是直接赋值给Global Env,而是首先在b的母环境,即创建的环境中检索,一旦检索到母环境有环境变量e,便立即赋值给这个环境变量中的对应变量值。
那么,来个简单的小结:
1. 对于函数内部变量的检索,如果在函数内部环境中无法找到,则到函数创建环境中检索,依次类推,知道Global Env.;
2. 对于"<-"函数内部变量的赋值符,检索规则与函数内部变量调用时的检索的规则无异;
3. 对于"<<-"函数变量的赋值符,检索时跳过函数内部环境,直接检索函数创建环境,直到找到变量为止,如果找不到,则赋值给Global Env.,如果变量前有环境变量限制,如env$var,如果Global Env.里也没有这个环境变量"env",则无法完成赋值。
0 0
- R: 如何理解变量和环境的Lexical Scoping Rule
- Lexical Scoping 和 Dynamic Scoping
- R’s Scoping
- R:环境和变量作用域的问题
- clojure 词法变量lexical和动态变量dynamic
- 如何理解继承成员变量和方法的区别?
- R Programming week2 Functions and Scoping Rules
- Emulating dynamic scoping in GNU R
- Lexical scope and function closures in R
- # 函数作用域之理解Scoping & Hoisting
- 从学习export命令理解到的Shell环境和变量生存期
- 从学习export命令理解到的Shell环境和变量生存期
- 从学习export命令理解到的Shell环境和变量生存期(转)
- 从学习export命令理解到的Shell环境和变量生存期
- 从学习export命令理解到的Shell环境和变量生存期
- R 如何给因子的类型变量修改元素
- 从Export理解Shell环境和变量生存期
- 从Export理解Shell环境和变量生存期
- 数据结构(C语言版)课后习题2.1
- ppt怎么转换成pdf具体方法
- 阿里2015实习生招聘 面试第一轮学习
- 如何复制dos窗口里的内容
- 物联12:rfidt系统安全概述
- R: 如何理解变量和环境的Lexical Scoping Rule
- boostASIO线程池
- ffmpeg2.6.2的使用过程和使用中发现的问题
- android音频(一)
- 函数栈空间
- input输入子系统框架分析
- 天声人語 20150421
- linux下的脚本运行的奇怪问题
- JSP介绍第一个JSP程序