困惑于...()?

Ari*_*man 43 r

另一个问题中,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

这是一个为什么...()按照它的方式工作的草图.我稍后会填写更多细节和参考资料,但这涉及到关键点.

  1. 在对其任何组件执行替换之前,substitute()首先解析R语句.

  2. ...()解析为调用对象,而...解析为名称对象.

  3. ...是一个特殊对象,仅用于函数调用.因此,实现替换的C代码会采取特殊措施来处理...在调用对象中找到它的时间.当作为符号出现时,采取类似的预防措施....(相关代码在函数do_substitutesubstitute,和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)

  • 继续这个奇怪的道路,试试这个:`substitute((...))`然后这个:`as.list(substitute((...)))`.似乎两种情况下的结果都是函数`'('`的"不正确"`call`对象,因为这个函数只接受一个参数.在第一种情况下,'print`假设它是一个正确的调用,并显示只有第一个参数.在第二种情况下,我们可以看到调用的所有元素. (2认同)