在另一个问题中,sapply(substitute(...()), as.character)在函数内部使用获取传递给函数的名称.这as.character部分听起来不错,但究竟是...()做什么的呢?
它不是有效的代码substitute:
> test <- function(...) ...()
> test(T,F)
Error in test(T, F) : could not find function "..."
Run Code Online (Sandbox Code Playgroud)
一些测试用例:
> test <- function(...) substitute(...())
> test(T,F)
[[1]]
T
[[2]]
F
> test <- function(...) substitute(...)
> test(T,F)
T
Run Code Online (Sandbox Code Playgroud)
Jos*_*ien 26
这是一个为什么...()按照它的方式工作的草图.我稍后会填写更多细节和参考资料,但这涉及到关键点.
在对其任何组件执行替换之前,substitute()首先解析R语句.
...()解析为调用对象,而...解析为名称对象.
...是一个特殊对象,仅用于函数调用.因此,实现替换的C代码会采取特殊措施来处理...在调用对象中找到它的时间.当作为符号出现时,不采取类似的预防措施....(相关代码在函数do_substitute中substitute,和substituteList(尤其是后两者)中R_SRCDIR/src/main/coerce.c.)
因此,()in 的作用...()是使语句被解析为调用(aka语言)对象,以便替换将返回点的完全扩展值....即使它位于外部也可能看起来令人惊讶(),但是:(a)调用内部存储为类似列表的对象,(b)相关的C代码似乎没有区分它的第一个元素列表和随后的列表.
只是旁注:为了检查substitute各种对象的行为或类,我发现设置一个小沙箱很有用,如下所示:
f <- function(...) browser()
f(a = 4, 77, B = "char")
## Then play around within the browser
class(quote(...)) ## quote() parses without substituting
class(quote(...()))
substitute({...})
substitute(...(..., X, ...))
substitute(2 <- (makes * list(no - sense))(...))
Run Code Online (Sandbox Code Playgroud)