R 函数中的名称屏蔽 - Hadley 的 Advanced R

Name masking in R function - Advanced R by Hadley

我在 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

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


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

的参数列表

如果我们仔细看看 j 及其一些属性,它可能会变得更清楚一些。

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

当我们查看它们的 类.

时,调用之间的差异变得非常明显
class(j(1))
# [1] "function"
class(j(1)())
# [1] "numeric"

当您定义 j 时,2 被硬编码到其 return 函数中作为向量的第二个值 return 从 that[=55] =] 函数。我们可以看到使用

调用 j(1) 的精确 return 值
library(pryr)
unenclose(j(1))
# function () 
# {
#     c(1, 2)
# }

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

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

希望对您有所帮助。

感谢 @Khashaa 提及 unenclose() 函数(评论已删除)。