R:了解省略号(...)在嵌套函数中的工作方式,以及iit如何工作

时间:2018-11-21 17:41:16

标签: r parameter-passing callstack

这就是我一直认为省略号在嵌套函数中起作用的方式:当您通过省略号将一组参数传递给某个函数时,调用堆栈上与其相关的任何函数都可以得到这些参数-我认为,通过它自己的省略号。我相信传递给省略号的参数是累积的,因此最前面的省略号包含在调用堆栈中优于它的任何函数中通过省略号参数传递的所有参数。

但是我只是做了一个实验来确认这一点,现在对我来说似乎是错误的。因此:

> f02 <- function(...){
+   vv <- list(...)
+   print(vv)
+ }
> f01 <- function(...){
+   f02(b = 2)
+ }
> f01(a=1)
$`b`
[1] 2

在这里,内部省略号似乎没有从外部省略号继承a=1参数。

所以我目前的理论是,当您采取要求的内容(例如list(…)match.call(expand.dots=TRUE)as.list(substitute(list(...)))[-1])的操作时,只会得到根据常规作用域规则下的搜索路径,遇到的的第一个实例。但是我不得不说,这对我来说似乎不太可能。如果为真,那么,如果其中一个函数具有一个自变量,则例如,多次调用提供给绘图函数的图形参数将遭受神秘的失败。

因此,我想知道是否存在一些特殊的规则来确定点对点中寻找的参数,例如,如果本地实例为空,则寻找上级实例,或者您在中寻找一个实例。特定的命名参数,例如list(...)$my_parameter,并且在那里找不到它。这些解决方案都没有使我感到非常合理,但是,我想出的解决方案都没有。

关于此主题的先前问题似乎主要集中于各种极端情况。我希望在正常情况下(但可能需要多层调用)理解传递规则。

2 个答案:

答案 0 :(得分:5)

必须显式提供省略号以传递给嵌套函数,因此,例如,在您的f02中,list调用将传递给f02的任何内容作为其自变量。相反,在f01中,仅忽略参数。您可以这样在f01内将参数传递给f02:

  f01 <- function(...){
  f02(b = 2,...)
}

结果:

f01(a=1)
$b
[1] 2

$a
[1] 1

不管省略号中有多少个参数,此方法均有效:

f01(a=1,c=3)
$b
[1] 2

$a
[1] 1

$c
[1] 3

答案 1 :(得分:0)

我希望论坛允许我发布答案,并且仍然接受iod的答案。这是我的意图。

看来我的原始信念(点累加了调用栈中提供给它们的所有参数)是正确的,前提是在两个中都包含了省略号(...函数定义和函数调用是第一个的所有调用。请参见下面的代码。对我来说,这建议...如果在链中某处的子功能可能需要在顶层提供的参数无法识别和传递,则应将...参数常规添加到嵌入在其他函数内部的函数调用中在编写函数时明确地。如果阅读此书的人有充分的理由相信这是个坏主意,我想听听。

请注意,尽管在调用函数2和3时必须使用省略号才能将其参数传递给内部,但在顶层禁止使用省略号,从而导致'...' used in an incorrect context错误。我感到困惑。鉴于辅助调用中允许使用点,因此我会期望出现'...' not found错误。

此外,我不明白为什么第三个参数的名称被报告为`c`。不是因为c是一个函数名;而是因为c1是一个函数名。 > f03 <- function(...){ + vv <- list(...) + print(vv) + } > f02 <- function(...){ + f03(c = 3, ...) + } > f01 <- function(...){ + f02(b = 2, ...) + } > f01(a = 1) $`c` [1] 3 $b [1] 2 $a [1] 1 也会发生相同的情况。

JAN 
FEB 
MAR 

APR 
MAY 
JUN 

JUL 
AUG 
SEP 

OCT 
NOV 
DEC 

Process finished with exit code 0