R 中的作用域和闭包
介绍
在本指南中,我们将介绍 R 编程语言的两个基本概念。首先,我们将阐明什么是作用域以及它是如何工作的。编程语言中有两种主要的作用域策略,我们将介绍 R 中使用的策略。之后,我们将介绍闭包的概念,并查看作用域和闭包的示例。
作用域
变量的作用域无非就是代码中引用和可见变量的位置。作用域有两个基本概念:词汇作用域和动态作用域。在 R 中,有一个自由变量的概念,它为作用域增添了一些趣味。在定义函数的环境中搜索此类变量的值。
让我们看一个自由变量的例子。
f <- function(a, b) {
(a * b) / z
}
在这个函数中,有两个形式参数a和b 。函数主体中还有另一个符号z ,它是一个自由变量。语言的作用域规则定义了如何将值分配给自由变量。R 使用词汇作用域,这意味着在定义函数的环境中搜索z的值。
注意:词汇作用域也称为静态作用域。
使用动态作用域,变量将绑定到分配给该变量的最新值。作用域还引入了另一个概念,称为范围。范围是在整个执行过程中可能发生引用的特定时间间隔。一个有趣的事实:词汇作用域起源于 1960 年,当时 John McCarthy 首次发表了关于 LISP 编程语言的原始论文。
R 提供了一些绕过词法作用域缺点的捷径。<-运算符称为变量赋值运算符。给定表达式a <- 3.14,将值分配给当前环境中的变量。如果您之前在同一环境中已经为该变量分配过,那么这次分配将覆盖它。变量赋值只会在当前环境中更新,并且永远不会创建新的作用域。当 R 寻找给定变量的值时,它会从底部开始搜索。这意味着首先检查当前环境,然后检查其封闭环境。搜索一直持续到找到值或到达空环境为止。
让我们演示一下查找。
a <- 3.14
b = function(x,y){ x * y / a}
b(10,11)
输出如下:
1] 35.03185
调用函数时,只传递两个参数。R 尝试查找a变量的值,并首先查看函数的作用域。由于无法在该作用域找到该值,它会在封闭作用域中查找该值,最终找到该值。如果您未定义 a变量,则会给出以下错误:Error in b(10, 11) : object 'a' not found,表示查找失败。
这引出了环境的概念。R 中的环境基本上是从变量到值的映射。每个函数都有一个本地环境和一个对封闭环境的引用。这有助于确定范围和查找。您可以选择添加、删除或修改变量映射,甚至可以更改对封闭环境的引用。
闭包
在 R 中,有一种称为“一等函数”的东西,其求值为闭包。函数体由函数体和求值函数的环境组成。这为创建根据所处环境改变操作的函数提供了可能性。在 R 中编程一段时间后,您习惯将函数作为参数传递,这些函数通常会返回结果。但是当您重新运行函数时,还有另一个方面。这允许您创建抽象并减少复杂性和时间投入问题。
假设你的人力资源部门想要一个能够将员工工资提高 5% 的功能。
hrfunction_5 <- function(base) { base * 1.05}
后来,该部门又提出另一个请求,这次是创建一个将工资增加 7% 的功能。
hrfunction_7 <- function(base) { base * 1.07}
各种薪资调整请求不断涌来。您决定寻求抽象的帮助并执行以下操作:
hrfunction <- function(incr){function(base){base * incr}}
从现在开始,您可以按照以下方式引用每个百分比:
hr_5 <- hrfunction(1.05)
hr_7 <- hrfunction(1.07)
hr_5(100)
hr_7(100)
输出应如下所示:
1] 105
[2] 107
您可能想知道hr_5和hr_7函数如何知道在哪里查找incr值。由于词法作用域,每个函数都带有对其定义环境的引用。当调用hr 函数时,incr参数将附加到返回函数的环境中。
结论
在本指南中,您了解了 R 的两个核心概念,更深入地了解了作用域的工作原理以及如何将其转化为优势。我希望本指南对您有所帮助,并感谢您阅读它。
免责声明:本内容来源于第三方作者授权、网友推荐或互联网整理,旨在为广大用户提供学习与参考之用。所有文本和图片版权归原创网站或作者本人所有,其观点并不代表本站立场。如有任何版权侵犯或转载不当之情况,请与我们取得联系,我们将尽快进行相关处理与修改。感谢您的理解与支持!
请先 登录后发表评论 ~