5

在 R 中,我注意到function运算符的解析树似乎是多余的,因为它的第四个元素似乎总是由前三个元素组成。

例如,

> as.list(substitute(function(x = 1){x^2}))
[[1]]
`function`

[[2]]
[[2]]$x
[1] 1


[[3]]
{
    x^2
}

[[4]]
function(x = 1){x^2}

我注意到的一件事是第四个元素确实存储了输入函数的格式。

> as.list(substitute(function(x = 1){
+ x^2})[[4]]
function(x = 1){
x^2}

解析树中第四个元素的目的是什么?我唯一能看到它被使用的是如果你想逐字打印一个函数,你已经可以通过打印函数来做到这一点,例如

> f = function(x = 1){
+ x^2}
> f
function(x = 1){
x^2}
4

2 回答 2

5

显然这个组件是一个源代码引用:它不容易在R 语言定义中定位,但它的目的正是为了保留原始源代码的结构,尤其是注释;例如

s <- substitute(function(x=1){ 
      ## a comment
       x^2})
str(s[[4]])
##  Class 'srcref'  atomic [1:8] 1 21 2 15 21 15 1 2
##   ..- attr(*, "srcfile")=Classes 'srcfilecopy', 'srcfile' <environment: 0x8a87634>

表明它是一个srcref对象。神秘的数字 (1, 21, 2, 15, ...) 表示对代表源代码的低级对象的索引,如?srcfile页面中所述(即c(first_line, first_byte, last_line, last_byte, first_column, last_column, first_parsed, last_parsed))。正如@SimonO101 所指出的,Duncan Murdoch 的 R Journal 文章可能给出了最好的解释。

于 2013-06-12T00:07:36.883 回答
2

一些附加说明:

1)可以使用options(keep.source=FALSE)(默认为TRUE)禁用此功能:

> as.list(substitute(function(x = 1){x^2}))
[[1]]
`function`

[[2]]
[[2]]$x
[1] 1


[[3]]
{
    x^2
}

[[4]]
NULL

其中list,第一个元素是标识闭包对象的符号,第二个元素保存formals,第三个保存body. 请注意,最后一个以“标准”方式打印。第四个元素将保存输入文本,如键入。

2) 如果你function(x = 1){x^2}在控制台输入,R 调用print.function,它接受一个useSource参数。这是TRUE默认情况下,并导致 R 简单地重复存储在解析列表的第四个元素中的内容。将其设置为FALSE强制 R 打印函数body

> options(keep.source=TRUE)
> f <- function(x = 1){x^2}
> f
function(x = 1){x^2}
> print.function(f)
function(x = 1){x^2}
> print.function(f, useSource=FALSE)
function (x = 1) 
{
    x^2
}
于 2013-06-12T12:47:11.277 回答