在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}
答案 0 :(得分:5)
显然这个组件是一个源引用:它不容易位于R language definition中,但其目的恰恰是保留原始源的结构,尤其是注释;例如
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指出的那样,R Journal article by Duncan Murdoch可能会给出最好的解释。
答案 1 :(得分: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
}