鉴于以下功能
f <- function(x) {
g <- function(y) {
y + z
}
z <- 4
x + g(x)
}
Run Code Online (Sandbox Code Playgroud)
如果在 R 中运行以下代码,为什么答案是 10?我对 y 如何处理这个问题有点困惑。
z <- 10
f(3)
Run Code Online (Sandbox Code Playgroud)
R 使用词法范围,这意味着如果一个对象被引用但未在函数中定义,那么它会在定义函数的环境中查找,而不是在调用它的环境中。
z 在 g 中引用但未在 g 中定义,因此它查看定义 g 的环境,即 f 中的环境,因此 g 使用 z = 4。
实际上,在这种情况下,定义 g 的环境与调用 g 的环境相同,因此无论您怎么看,都必须使用 z = 4。如果函数默认使用全局环境来查找函数中未定义的对象,那么它将使用 z = 10 但这不是 R 的工作方式。
如果出于某种原因,您想强制 g 在调用 f 的环境中查找 z,那么您可以这样做( whereparent.frame()指的是调用 f 的环境)。
f2 <- function(x, envir = parent.frame()) {
g <- function(y) {
y + with(envir, z)
}
z <- 4
x + g(x)
}
z <- 10
f2(3)
## [1] 16
Run Code Online (Sandbox Code Playgroud)
或者我们可以使用y + envir$z除了它只会在父框架中而不是在其祖先中with查找,而如果在父框架中找不到,则将在父框架的祖先中查找。
另一种方法是像这样更改 g 的环境,以便它查找envir在 g 中找不到的对象:
f3 <- function(x, envir = parent.frame()) {
g <- function(y) {
y + z
}
environment(g) <- envir
z <- 4
x + g(x)
}
z <- 10
f3(3)
## [1] 16
Run Code Online (Sandbox Code Playgroud)