R verwendet lexikalisches Scoping. Wenn ein Objekt referenziert, aber nicht in einer Funktion definiert ist, wird es in der Umgebung gesucht, in der die Funktion definiert ist , und nicht in der Umgebung, aus der es aufgerufen wurde.
z wird in g referenziert, aber nicht in g definiert, so dass es sich um die Umgebung handelt, in der g definiert ist, und das ist die Umgebung innerhalb von f, also verwendet g z = 4.
Tatsächlich ist in diesem Fall die Umgebung, in der g definiert ist, dieselbe wie die Umgebung, aus der g aufgerufen wird. Daher muss jede Art, wie Sie es betrachten, z = 4 verwendet werden. Wenn Funktionen standardmäßig in der globalen Umgebung nach Objekten suchen, die nicht in der Funktion definiert sind, wird z = 10 verwendet, aber so funktioniert R nicht.
Damit es anders funktioniert
Wenn Sie aus irgendeinem Grund g zwingen möchten, in der Umgebung, in der f aufgerufen wird, nach z zu suchen, können Sie dies tun (wobei parent.frame()
sich auf die Umgebung bezieht, aus der f aufgerufen wird).
f2 <- function(x, envir = parent.frame()) {
g <- function(y) {
y + with(envir, z)
}
z <- 4
x + g(x)
}
z <- 10
f2(3)
## [1] 16
oder wir könnten verwenden, y + envir$z
außer dass dies nur im übergeordneten Frame und nicht in seinen Vorfahren angezeigt with
wird, wohingegen Vorfahren des übergeordneten Frames angezeigt werden, wenn sie nicht im übergeordneten Frame gefunden werden.
Eine Alternative besteht darin, die Umgebung von g so zu ändern, dass envir
nach Objekten gesucht wird, die nicht in g gefunden wurden:
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