以下代码来自Hadley Wickham撰写的 Advanced R 一书。它是lapply
函数中的函数,不确定它是否有资格作为函数,但除此之外。代码由两个函数add()
组成,定义为:
add <- function(x) {
function(y) x+y
}
然后他使用add()
和adders
“对象”,它的行为就像一个函数,但我不理解逻辑。我说它的行为就像一个函数,因为你可以像这样adders[[1]](10)
编写代码,所以看起来adders[[1]]
是一个函数。无论如何,他将adders
定义为:
adders <- lapply(1:10,add)
在我看来,adders[[1]](10)
中的10是add()
函数中的“y”值。 1:10中的部分通过lapply
表示add()
函数的x,但是我不确定我是否理解逻辑。
答案 0 :(得分:4)
此外,加法器[[x]]的行为就像一个函数,我们没有定义 它作为一种功能,至少不是经典的功能方式 定义加法器&lt; - function(x){---}
大概是通过&#34;经典方式&#34;,你的意思是一个命名函数,并指的是add
中的最后一行:
function(y) x + y
与上述功能一样,函数不必具有关联名称 - 这些名称称为匿名函数。例如,您可以尝试运行
(function(a, b) a + b)(1, 2)
它会被立即评估,返回3 - 即使你没有将它分配给一个名字。由于它没有被分配给任何东西,它在完成评估后就会消失。另请注意以下事项:
class((function(a, b) a + b))
#[1] "function"
这是推动这个家庭的另一个例子:
add <- function(x) {
force(x)
function(y) x + y
## ^^^^^^^^^^^
## functionally equivalent to:
##
## f <- function(y) x + y
## return(f)
}
add_explicit <- function(x) {
force(x)
f <- function(y) x + y
return(f)
}
(add(5))
#function(y) x + y
#<environment: 0x64106b0>
(add_explicit(5))
#function(y) x + y
#<environment: 0x637fe58>
虽然可以创建一个命名函数,但在add_explicit
中,因为您实际上并没有按名称调用它(至少在您的问题的上下文中),这样做没有意义。
[...]但仍然与&#34; y&#34;混淆,如何访问和填写? 因为当你写加法器时[1]。 5分配给y,但它 感觉它应该去&#34; x&#34;因为当你编码add()时x是 内部唯一的元素()。
让我们将David Arenburg关于检查功能环境的建议应用于add(...)
和add_explicit(...)
:
ls.str(envir = environment(add(42)))
#x : num 42
ls.str(envir = environment(add_explicit(42)))
#f : function (y)
#x : num 42
关于adders[[1]](5)
- 相当于add(1)(5)
,因为用于创建它的表达式是lapply(1:[whatever], add)
- 你说你觉得5应该对应x
参数而不是(嵌套的)y
参数。但正如上面的检查所示,x
实际上不再是一个函数参数 - 它的值是&#34;固定的&#34;无论在add(x)
被召唤时它是什么 - 在我的情况下是42。由于add
返回了匿名函数,x
是所有相应的环境显示。另一方面,add_explicit
将表达式分配给名称(在其关联的环境中),您可以看到f
仅是的函数 y
。因此,当您致电add([whatever])(5)
时, 就是5
对应y
正文中的add
变量的原因。
另外,请勿过多地挂在adders
对象上。它恰好是list
恰好存储函数,即:
lapply(1:2, add)
#[[1]]
#function (y)
#x + y
#<environment: 0x7425ce0>
#[[2]]
#function (y)
#x + y
#<environment: 0x74259d0>
虽然似乎出现 x
在这样检查时仍然是(变化的)参数,但其值已经修复(在第一种情况下为1
,和2
以及第二种情况)。这一部分真正重要的是 - function (y)
- 表示由list
创建的lapply
包含接受单个参数(y
)的函数。 x
已经有效地摆脱了桌面的影响。就名单而言。