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始终是全球的严格子集?如果明智,我该怎么做?
以上不起作用,因为
fa并fb没有在f2环境中定义.
不 - 他们是.错误完全不同:
f1 <- function(x, y){f(x)^y}
Run Code Online (Sandbox Code Playgroud)
在这里您使用的是未定义的变量f,这是一个错误.
你有一个不同的变量(容易混淆f)f2.然而,这无关f1,因为f1并f2没有分享他们的局部变量.如果你想传递f2的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"
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可插入但隔离效果以避免引入全局可修改状态.这是函数式编程语言的标准代码,但在函数式语言之外则不常见,因此对某些人来说有点令人惊讶.