R语言 动态范围
R是一种开源的编程语言,作为统计软件和数据分析工具被广泛使用。R通常带有命令行界面。R可以在Windows、Linux和macOS等广泛使用的平台上使用。而且,R编程语言是最新的尖端工具。R语言的范围界定规则是使其不同于原始S语言的主要特征。R语言使用词法范围或静态范围。一个常见的选择是 动态范围 。
动态范围背后的概念
考虑下面这个函数。
f <- function(x, y){
x^2 + y/z
}
这个函数有2个形式参数x和y,在函数的主体中,还有一个符号z,在这种情况下,z是一个自由变量。一种语言的范围规则决定了如何向自由变量赋值。自由变量不是形式参数,也不是局部变量(在主体内分配)。R语言中的词法范围意味着自由变量的值是在定义函数的环境中搜索的。搜索自由变量的值意味着。
- 如果在定义函数的环境中没有找到该符号的值,那么就在父环境中继续搜索。
- 沿着父环境的序列继续搜索,直到用户碰到顶层环境;这通常是全局环境(工作区)或包的命名空间。
- 如果在空环境中找不到某个符号的值,那么就会产生一个错误。自由变量的值在下图中给出。
通常情况下,一个函数被定义在全局环境中,这样自由变量的值就可以在用户的工作空间中找到,但是在R中,人们可以将函数定义在其他函数中。例如,请看下面的代码。
make.power <- function(n){
pow <- function(x){
x = x^n
}
pow
}
cube <- make.power(3)
square <- make.power(2)
print(cube(3))
print(square(3))
输出:
[1] 27
[1] 9
power函数接受参数x,并提高了n的功率。因此,这使得函数pow在函数值内返回。n是一个自由变量,在pow函数中被定义。函数环境里有什么?
ls(environment(cube))
[1] "n" "pow"
get("n", environment(cube))
[1] 3
ls(environment(square))
[1] "n" "pow"
get("n", environment(square))
[1] 2
让我们考虑另一个例子
y <- 10
# creating a function f which takes argument x
f <- function(x){
# y is free variable
y <- 2
# g function is also a free variable
# not defined in the scope of function
y^2 + g(x)
}
g <- function(x){
# y is free variable
# value of y in this function is 10
x*y
}
在这种情况下,y的值是什么?
- 在词法范围内,函数g中y的值是在定义函数的环境中查找的,在本例中是全局环境,所以y的值是10。
- 在动态范围内,y的值是在调用函数的环境中查找的(有时被称为调用环境)。
- 在R中,调用环境被称为父框架。所以y的值是2。
当一个函数被定义在全局环境中并随后被从全局环境中调用时,那么定义环境和调用环境是相同的。这有时会给人一种动态范围的感觉
g <- function(x){
a <- 3
# in this case x is function a formal argument and
# a is local variable and
# y is free variable
x + a + y
}
# printing value of g(2)
print(g(2))
如果我们调用g(2),会出现如下错误。
输出:
Error in g(2) : object 'y' not found
在给y赋值后调用g(2),如下所示。
g <- function(x){
a <- 3
x + a + y
}
# assigning value to y
y <- 3
# print g(2)
print(g(2))
输出:
[1] 8