冻结在另一个函数中调用的函数

Freeze a function called in an other one

我在想 R 既不使用指针也不使用引用。但是,我遇到了将动态更改为函数的问题。这是一个 MWE 来阐明我的观点:

> a = function(x) 2
> b = function(x) a(x)
> b(4)
[1] 2
> a = function(x) 3
> b(4)
[1] 3

虽然我期待改变 a 但不会改变 b。例如,如果我这样做:

> a = function(x) 2
> b  = a
> b(4)
[1] 2
> a = function(x) 3
> b(4)
[1] 2

我理解在第一种情况下没有复制 a;相反,每次我调用 b 时,R 都会在 GlobalEnvir 中寻找一个函数 a,而在第二个调用中,它会制作一个副本,对吗?但是,如果我的函数 a 被迭代修改,而我希望 b 在我定义 b 的正确时刻使用它,那么正确的方法是什么。现在,我想使用 a:

的副本
> a = function(x) 2
> aa = a
> b = function(x) aa(x)
> b(4)
[1] 2
> a = function(x) 3
> b(4)
[1] 2

但是如果我更新 a 不止一次(因为我也会更新 aa),这将不起作用。

谢谢

这是一个范围问题。您可以强制 b 在特定环境中评估 a。例如这里使用 local:

的解决方案
for(y in 1:5){
  b <- local({
    a = function(x) paste("old",x,y)
    function(x)  a(x)
  })
  a = function(x) paste("new",x,y)
  print(b(4))
}

[1] "old 4 1"
[1] "old 4 2"
[1] "old 4 3"
[1] "old 4 4"
[1] "old 4 5"

local 将计算局部环境中的表达式。它创建了一个新的空环境

@agstudy 答案很好,但如果 a 是一个黑盒子,并且使用它的解决方案,技巧可能是:

a = function(x) "old"
b = local({
    aa = a
    function(x) aa(x)
})

然后 aaa 都可以更改,而 b 仍将使用原始值定义:

a = function(x) "new"
b(1)
[1] "old"
aa = function(x) "aa has changed"
b(1)
[1] "old"