功能不能看到""在全球环境中定义的其他功能

时间:2016-11-23 16:21:49

标签: r scope 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"

上述方法无效,因为f未在f1的环境中定义。

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

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

定义某种&#34; subglobal&#34;是否有意义?环境,并把我希望每个人都在这个环境中使用的东西,然后让每个功能都能够访问来自&sub; global&#34 ;?的东西。然后以某种方式确保subglobal始终是全球的严格子集?如果明智,我该怎么做?

1 个答案:

答案 0 :(得分:7)

  

上述方法无效,因为fafb未在f2的环境中定义。

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

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

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

f内有不同的变量(令人困惑地也称为f2)。但是,这与f1无关,因为f1f2不共享其本地变量。如果您想将f2的{​​{1}}传递给f,那么您需要将其作为参数传递。

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

f1

这是修复:

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"
f_exp = function (x, y, g) g(x) ^ y

或者,如果您在f_exp(x, y, f) 内多次调用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) } 可插入但隔离效果以避免引入全局可修改状态。这是函数式编程语言的标准代码,但在函数式语言之外则不常见,因此对某些人来说有点令人惊讶。