R:我可以让函数的执行环境永久化吗?
R: Could I make the execution environment of a function permanent?
我正在研究 R 环境,但在阅读 Hadley Wickham 的“Advanced R”一书时遇到了问题。是否可以让一个函数的执行环境永久化?
我会尝试解释我的问题的原因。
当 Wickham 解释函数的执行环境如何工作时,显示了以下示例:
j <- function() {
if (!exists("a")) {
a <- 1
} else {
a <- a + 1
}
print(a)
}
j()
我明白为什么每次调用函数 j
时返回值都是 1。
在文本的另一部分,他说:
When you create a function inside another function, the enclosing
environment of the child function is the execution environment of the
parent, and the execution environment is no longer ephemeral.
所以我想创建以下函数:
j <- function() {
if (!exists("a")) {
a <- 1
} else {
a <- a + 1
}
print(a)
g <- function() {}
g()
}
j()
但是返回值一直是1,估计是因为执行环境每次都在继续被破坏。 “不再短暂”是什么意思?
函数内的永久环境称为“闭包”。这里有一个玩具示例来演示这一点。检查一下,然后相应地修改您的代码。
closure <- function(j) {
i <- 1
function(x) {
i <<- i + 1
j * i + x
}
}
i <- 12345
instance <- closure(11)
instance(3)
#[1] 25
instance(3)
#[1] 36
instance(3)
#[1] 47
otherObj <- closure(2)
otherObj(3)
#[1] 7
instance(2)
#[1] 57
根据本书,还可以使用函数工厂结构(创建另一个函数的函数)来捕获第一个函数的临时执行环境。以下示例只是我们如何捕获它的一种简单方法:
library(rlang)
j <- function() {
print(current_env())
a <- 1
k <- function() {
if (!exists("a")) {
a <- 1
} else {
a <- a + 1
}
print(a)
}
}
plus <- j()
> plus <- j()
<environment: 0x000001ca98bc1598>
现在无论你使用函数plus
多少次,它的环境永远是第一个函数当时的执行环境:
library(rlang)
env_print(plus)
<environment: 000001CA98BC1598>
parent: <environment: global>
bindings:
* k: <fn>
* a: <dbl>
plus()
[1] 2
env_print(plus)
<environment: 000001CA98BC1598>
parent: <environment: global>
bindings:
* k: <fn>
* a: <dbl>
我希望这在一定程度上回答了您的问题,但可能还有更好的答案。
我正在研究 R 环境,但在阅读 Hadley Wickham 的“Advanced R”一书时遇到了问题。是否可以让一个函数的执行环境永久化?
我会尝试解释我的问题的原因。
当 Wickham 解释函数的执行环境如何工作时,显示了以下示例:
j <- function() {
if (!exists("a")) {
a <- 1
} else {
a <- a + 1
}
print(a)
}
j()
我明白为什么每次调用函数 j
时返回值都是 1。
在文本的另一部分,他说:
When you create a function inside another function, the enclosing environment of the child function is the execution environment of the parent, and the execution environment is no longer ephemeral.
所以我想创建以下函数:
j <- function() {
if (!exists("a")) {
a <- 1
} else {
a <- a + 1
}
print(a)
g <- function() {}
g()
}
j()
但是返回值一直是1,估计是因为执行环境每次都在继续被破坏。 “不再短暂”是什么意思?
函数内的永久环境称为“闭包”。这里有一个玩具示例来演示这一点。检查一下,然后相应地修改您的代码。
closure <- function(j) {
i <- 1
function(x) {
i <<- i + 1
j * i + x
}
}
i <- 12345
instance <- closure(11)
instance(3)
#[1] 25
instance(3)
#[1] 36
instance(3)
#[1] 47
otherObj <- closure(2)
otherObj(3)
#[1] 7
instance(2)
#[1] 57
根据本书,还可以使用函数工厂结构(创建另一个函数的函数)来捕获第一个函数的临时执行环境。以下示例只是我们如何捕获它的一种简单方法:
library(rlang)
j <- function() {
print(current_env())
a <- 1
k <- function() {
if (!exists("a")) {
a <- 1
} else {
a <- a + 1
}
print(a)
}
}
plus <- j()
> plus <- j()
<environment: 0x000001ca98bc1598>
现在无论你使用函数plus
多少次,它的环境永远是第一个函数当时的执行环境:
library(rlang)
env_print(plus)
<environment: 000001CA98BC1598>
parent: <environment: global>
bindings:
* k: <fn>
* a: <dbl>
plus()
[1] 2
env_print(plus)
<environment: 000001CA98BC1598>
parent: <environment: global>
bindings:
* k: <fn>
* a: <dbl>
我希望这在一定程度上回答了您的问题,但可能还有更好的答案。