R sử dụng phạm vi từ vựng có nghĩa là nếu một đối tượng được tham chiếu nhưng không được xác định trong hàm thì nó được tìm kiếm trong môi trường mà hàm được định nghĩa , không phải là môi trường mà nó được gọi.
z được tham chiếu trong g nhưng không được xác định bằng g nên nó nhìn vào môi trường trong đó g được xác định và đó là môi trường trong f nên g sử dụng z = 4.
Trên thực tế trong trường hợp này, môi trường mà g được định nghĩa giống như môi trường mà g được gọi vì vậy bất kỳ cách nào bạn nhìn vào nó z = 4 đều phải được sử dụng. Nếu các hàm được mặc định cho môi trường toàn cầu để tìm kiếm các đối tượng không được xác định trong hàm thì nó sẽ sử dụng z = 10 nhưng đó không phải là cách R hoạt động.
Làm cho nó hoạt động khác nhau
Nếu vì lý do nào đó bạn muốn buộc g tìm kiếm z trong môi trường mà f được gọi thì bạn có thể làm điều này (trong đó parent.frame()
đề cập đến môi trường mà f được gọi).
f2 <- function(x, envir = parent.frame()) {
g <- function(y) {
y + with(envir, z)
}
z <- 4
x + g(x)
}
z <- 10
f2(3)
## [1] 16
hoặc chúng ta có thể sử dụng y + envir$z
ngoại trừ cái đó chỉ nhìn vào khung cha mẹ chứ không with
nhìn vào tổ tiên của nó trong khi sẽ tìm trong tổ tiên của khung cha nếu không tìm thấy trong khung cha.
Một cách khác là thay đổi môi trường của g như thế này để nó nhìn vào envir
các đối tượng không tìm thấy trong 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