了解嵌套函数的作用域
Understanding scoping of nested functions
我正在尝试通过将脚本拆分为多个函数来重构脚本,其中包含一个主要函数和“帮助函数”。在这里,我偶然发现了一个可以简化为以下示例的问题:
g <- function(a,b){ # help function
a^2 + b^2 - c
}
f <- function(a,b,c,d){ # main function
g(a,b)
}
这里的问题是,f
无法计算,因为 g
不知道 c
是什么,但为什么会这样呢?
我读过 here 如果 R 不知道函数中的 variable/argument,它会在外部 function/environment 中搜索缺失的 variable/argument。
为什么 g
仍然不知道 f
声明的值 c
?
R 使用词法作用域,这意味着如果一个函数需要引用一个未在该函数中定义的对象,它会查看函数 定义 的环境,而不是调用者.在问题中,g 是在全局环境中定义的,因此 g 会在其中查找 c。
另请注意,在 R 中,我们不会调用问题嵌套函数中的函数。相反,嵌套的是调用,而不是函数。在下面的 (3) 中,我们展示了嵌套函数。
1) 我们可以重置一个函数的环境,在这种情况下它会认为它是在那个环境中定义的。
g <- function(a,b){ # help function
a^2 + b^2 - c
}
f <- function(a,b,c,d){ # main function
environment(g) <- environment()
g(a,b)
}
f(1, 2, 3, 4)
## [1] 2
2) 另一种可能性是使用 envir$c(其中 envir 是所需环境)或 get("c", envir) 明确告诉它搜索哪个环境与(环境,c)。 envir$c 将调查 envir。另外两个将在那里寻找,如果找不到,将查看祖先环境。 (每个环境都有一个父级或 emptyenv()。这与调用堆栈不同。)
g <- function(a, b, envir = parent.frame()){ # help function
a^2 + b^2 - envir$c
}
f <- function(a,b,c,d){ # main function
g(a,b)
}
f(1, 2, 3, 4)
## [1] 2
3)我们可以嵌套函数,让g在f中定义。
f <- function(a,b,c,d){ # main function
g <- function(a,b){ # help function
a^2 + b^2 - c
}
g(a,b)
}
f(1, 2, 3, 4)
## [1] 2
4)当然你可以直接通过c,避免所有这些问题。
我正在尝试通过将脚本拆分为多个函数来重构脚本,其中包含一个主要函数和“帮助函数”。在这里,我偶然发现了一个可以简化为以下示例的问题:
g <- function(a,b){ # help function
a^2 + b^2 - c
}
f <- function(a,b,c,d){ # main function
g(a,b)
}
这里的问题是,f
无法计算,因为 g
不知道 c
是什么,但为什么会这样呢?
我读过 here 如果 R 不知道函数中的 variable/argument,它会在外部 function/environment 中搜索缺失的 variable/argument。
为什么 g
仍然不知道 f
声明的值 c
?
R 使用词法作用域,这意味着如果一个函数需要引用一个未在该函数中定义的对象,它会查看函数 定义 的环境,而不是调用者.在问题中,g 是在全局环境中定义的,因此 g 会在其中查找 c。
另请注意,在 R 中,我们不会调用问题嵌套函数中的函数。相反,嵌套的是调用,而不是函数。在下面的 (3) 中,我们展示了嵌套函数。
1) 我们可以重置一个函数的环境,在这种情况下它会认为它是在那个环境中定义的。
g <- function(a,b){ # help function
a^2 + b^2 - c
}
f <- function(a,b,c,d){ # main function
environment(g) <- environment()
g(a,b)
}
f(1, 2, 3, 4)
## [1] 2
2) 另一种可能性是使用 envir$c(其中 envir 是所需环境)或 get("c", envir) 明确告诉它搜索哪个环境与(环境,c)。 envir$c 将调查 envir。另外两个将在那里寻找,如果找不到,将查看祖先环境。 (每个环境都有一个父级或 emptyenv()。这与调用堆栈不同。)
g <- function(a, b, envir = parent.frame()){ # help function
a^2 + b^2 - envir$c
}
f <- function(a,b,c,d){ # main function
g(a,b)
}
f(1, 2, 3, 4)
## [1] 2
3)我们可以嵌套函数,让g在f中定义。
f <- function(a,b,c,d){ # main function
g <- function(a,b){ # help function
a^2 + b^2 - c
}
g(a,b)
}
f(1, 2, 3, 4)
## [1] 2
4)当然你可以直接通过c,避免所有这些问题。