R如何知道不使用旧的'f'?

gob*_*lin 4 r

进入R控制台,输入:

#First code snippet
x <- 0
x <- x+1
x
Run Code Online (Sandbox Code Playgroud)

你会得到'1'.这是有道理的:这个想法是'x + 1'中的'x'是x的当前值,即0,这用于计算x + 1的值,即1,然后将其铲入容器x.到现在为止还挺好.

现在输入:

#Second code snippet
f <- function(n) {n^2}
f <- function(n) {if (n >= 1) {n*f(n-1)} else {1}}
f(5)
Run Code Online (Sandbox Code Playgroud)

你会得到'120',这是5阶乘.

我觉得这很令人困惑.遵循第一个代码片段的逻辑,我们可能期望表达式中的'f'

if (n >= 1) {n*f(n-1)} else {1}
Run Code Online (Sandbox Code Playgroud)

被解释为f的当前值,即

function(n) {n^2}
Run Code Online (Sandbox Code Playgroud)

根据这个推理,f(5)的值应该是5*(5-1)^ 2 = 80.但这不是我们得到的.

题.这里到底发生了什么?R如何知道不使用旧的'f'?

Kon*_*lph 12

我们可能期望表达式中的'f'

if (n >= 1) {n*f(n-1)} else {1}
Run Code Online (Sandbox Code Playgroud)

被解释为f的当前值

- 是的,我们可以期待.我们会是正确的.

但是什么是"当前的价值f"?或者,更准确地说,什么是"当前"?

"当前"是执行功能时,而不是定义时.也就是说,到执行时f(5),它已经被重新定义.所以现在执行进入功能,查找里面的功能是什么f指的是-并且还找出当前(=新)定义,而不是旧的.

换句话说:在实际访问名称时,会查找与名称关联的对象.在函数内部,这意味着在执行函数时访问名称,而不是在定义函数时访问.

所有对象都是如此.假设f使用的是一个不是函数的全局对象:

n = 5
f = function() n ^ 2

n = 1
f() # = 1
Run Code Online (Sandbox Code Playgroud)

要理解第一个和第二个示例之间的区别,请考虑以下涉及函数的情况,但行为与第一个案例相似(即它使用"旧"值f).

为了使示例有效,我们需要一个小帮手:一个修改其他函数的函数.在下文中,twice是一个函数,它将函数作为参数并返回一个新函数.该新函数与旧函数相同,只在调用时运行两次:

twice = function (original_function) {
    force(original_function)
    function (...) {
        original_function(original_function(...))
    }
}
Run Code Online (Sandbox Code Playgroud)

为了说明是什么twice,让我们在示例函数上调用它:

plus1 = function (n) n + 1
plus2 = twice(plus1)
plus2(3) # = 5
Run Code Online (Sandbox Code Playgroud)

Neat-R允许我们像任何其他对象一样处理函数!

现在让我们修改你的f:

f = function(n) {n^2}
f = twice(f)
f(5) # 625
Run Code Online (Sandbox Code Playgroud)

......在这里我们有它:在声明中f = twice(f),第二个f引用当前(=旧)定义.只有在该行之后才会f引用新的修改函数.

  • 我想知道从函数中删除时基本行为是否更容易掌握:`n < - 5; f < - function(){n ^ 2}; n < - 1; f()`返回1而不是25.```中`n`的值是在运行时确定的,而不是在函数创建时确定的. (2认同)