📜  R 编程中的动态范围

📅  最后修改于: 2022-05-13 01:54:41.817000             🧑  作者: Mango

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