R函数中的名称屏蔽 - Hadley的高级R.

时间:2015-01-25 05:08:41

标签: r function

我在Hadley的Advanced R中遇到了这个例子。我的问题是在定义函数之后,j(1)将内部函数定义输出为j(1)()输出的内容?直观地说,我认为j(1)应该输出[1] 1 2

有人能解释实际发生了什么吗? j(1)和j(1)()之间有什么区别?

> j <- function(x) {
+   y <- 2
+   function() {
+     c(x,y)
+   }
+ }

> k <- j(1)

> k()
[1] 1 2

> j(1)
function() {
    c(x,y)
  }
<environment: 0x7fa184353bf8>

> j()
function() {
    c(x,y)
  }
<environment: 0x7fa18b5ad0d0>

> j(1)()
[1] 1 2

1 个答案:

答案 0 :(得分:6)

tl; dr 在R中,函数的返回值也可以是函数。就是这种情况。 j(1)返回一个函数,而j(1)()返回一个数字向量。


j(1)j(1)()之间的区别在于j(1)输出一个函数,因为它是j定义中的最后一个值。函数返回它们的最后一个表达式(或在相关的return()调用中找到的值),在这种情况下,它也是一个函数。 j(1)()正在调用j的最后一个值,这是从它返回的函数。它不带参数,因此空括号()j(1)的参数列表

如果我们仔细研究一下j及其一些属性,可能会更清楚一些。

j <- function(x) {
    y <- 2
    function() {
        c(x, y)
    }
}

当我们查看他们的课程时,调用之间的差异变得非常明显。

class(j(1))
# [1] "function"
class(j(1)())
# [1] "numeric"

当你定义j时,2被硬编码到它的返回函数中,作为从 函数返回的向量的第二个值。我们可以看到使用

调用j(1)的确切返回值
library(pryr)
unenclose(j(1))
# function () 
# {
#     c(1, 2)
# }

因此,对j(1)()(或k())的调用将传递向量c(1, 2)。同样,如果我们致电j(5),则j(5)()的返回值为c(5, 2)

unenclose(j(5))
# function () 
# {
#     c(5, 2)
# }

希望有所帮助。

感谢@Khashaa提及unenclose()功能(删除评论)。