咨询:R语言嵌套函数中get/getAnywhere无法找到参数的原因
为什么
get()/getAnywhere()找不到嵌套函数的内部参数? 这个问题的核心在于R的词法作用域(Lexical Scoping)规则,咱们一步步拆解清楚:
1. 函数的「出生环境」决定了它的变量查找路径
R里的函数会牢牢记住自己被定义时所在的环境(也就是「词法环境」),而不是调用它时所处的环境。看你的代码:
g <- function(){ get("input") } # g定义在全局环境里 h <- function(input){ g() } # h同样定义在全局环境,调用g时,g的查找链还是从它的定义环境(全局)开始
当你调用h(1:3)时,input是存放在h的局部执行环境里的,但g的环境查找链是:g的执行环境 → 全局环境 → 空环境,这条链里根本不包含h的局部环境,自然找不到input。
2. get()的默认行为是顺着词法环境链查找
get()函数默认的envir参数是parent.frame(),也就是当前函数的词法父环境,而非调用它的那个函数的环境。所以哪怕g是在h内部被调用的,它依然只会沿着自己的定义环境往上找,不会跳到h的局部环境里去搜变量。
3. 怎么让g()能找到input?
有两种简单的解决思路:
- 把
g定义在h内部:这样g的词法环境就变成了h的环境,查找链会包含h的局部环境:h <- function(input){ g <- function(){ get("input") } g() } h(1:3) # 现在能正常返回1:3了 - 手动指定
get()的查找环境:如果非要让全局定义的g找到h里的input,可以把h的局部环境传给g:g <- function(target_env){ get("input", envir = target_env) } h <- function(input){ g(target_env = environment()) } h(1:3) # 同样能返回1:3
这里environment()在h内部调用时,返回的就是h当前的局部执行环境,把它传给get()的envir参数,就能精准找到input了。
关于getAnywhere()的补充
getAnywhere()会搜索所有已加载的命名空间和全局环境,但它不会搜索函数的临时局部执行环境(这类环境在函数执行完毕后就会被销毁),所以哪怕你在g里调用getAnywhere("input"),也找不到h里的input——它根本不会去遍历函数的局部环境。
内容的提问来源于stack exchange,提问作者Thom Quinn
相关产品推荐
相关产品推荐

