R 编程中的动态范围
R 是一种开源编程语言,被广泛用作统计软件和数据分析工具。 R 通常带有命令行界面。 R 可用于广泛使用的平台,如 Windows、Linux 和 macOS。此外,R 编程语言是最新的尖端工具。 R 的作用域规则是使其不同于原始 S 语言的主要特征。 R 语言使用词法范围或静态范围。一个常见的替代方法是动态范围。
动态范围的概念
考虑以下函数:
R
f <- function(x, y){
x^2 + y/z
}
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))
R
ls(environment(cube))
R
get("n", environment(cube))
R
ls(environment(square))
R
get("n", environment(square))
R
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
}
R
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))
R
g <- function(x){
a <- 3
x + a + y
}
# assigning value to y
y <- 3
# print g(2)
print(g(2))
这个函数有 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
幂函数接受参数 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