功能无法"看到"全局环境中定义的其他功能

gen*_*ser 1 scope r s

fa <- function(x){x+1}
fb <- function(x){x-1}

f1 <- function(x, y){f(x)^y}

f2 <- function(x, ab, y){
   if(ab == 'a'){
     f <- fa
   } else {
     f <- fb
   }
   f1(x, y)
}

f2(0, 'a', .5)
Error in f1(x, y) : could not find function "f"
Run Code Online (Sandbox Code Playgroud)

上述方法不起作用,因为f未在f1环境中定义.

什么是使这项工作的好方法?那

  • 避免将全球环境中的所有内容传递到f2环境中
  • 避免不得不重新定义内部功能f2(这将是一个麻烦,并创建复制/粘贴错误的机会)

定义某种"亚全球"环境,并将我希望每个人都在这个环境中使用的东西放在一起,然后让每个函数都能够从"subglobal"访问它们是否有意义?然后以某种方式确保subglobal始终是全球的严格子集?如果明智,我该怎么做?

Kon*_*lph 7

以上不起作用,因为fafb没有在f2环境中定义.

不 - 他们.错误完全不同:

f1 <- function(x, y){f(x)^y}
Run Code Online (Sandbox Code Playgroud)

在这里您使用的是未定义的变量f,这是一个错误.

你有一个不同的变量(容易混淆f)f2.然而,这无关f1,因为f1f2没有分享他们的局部变量.如果你想传递f2ff1,那么你需要将它作为参数传递.

顺便提一下,您的变量名称如此相似的事实使得这比必要的更复杂.如果您将代码更改为以下等效代码,则问题会变得更加清晰:

plus1 = function (x) x + 1
minus1 = function (x) x - 1

f_exp = function (x, y) g(x) ^ y

plusminus_exp = function (x, ab, y) {
    if (ab == 'a')
        f = plus1
    else
        f = minus1
    f_exp(x, y)
}

plusminus_exp(0, 'a', .5)
# Error in f_exp(x, y) : could not find function "g"
Run Code Online (Sandbox Code Playgroud)

这是修复:

f_exp = function (x, y, g) g(x) ^ y
Run Code Online (Sandbox Code Playgroud)
f_exp(x, y, f)
Run Code Online (Sandbox Code Playgroud)

或者,如果您在f_exp内部多次调用,则plusminus_exp可以使用一些更高级的抽象来创建函数构建器:返回另一个函数的函数:

make_f_exp = function (f) {
    force(f)
    function (x, y)
        f(x) ^ y
}

plusminus_exp = function (x, ab, y) {
    f = if (ab == 'a') plus1 else minus1
    f_exp = make_f_exp(f)
    f_exp(x, y)
}
Run Code Online (Sandbox Code Playgroud)

这使得f_exp可插入但隔离效果以避免引入全局可修改状态.这是函数式编程语言的标准代码,但在函数式语言之外则不常见,因此对某些人来说有点令人惊讶.