R:了解省略号 (...) 如何在嵌套函数中工作,以及 iit 如何不工作
R: Understanding how ellipsis (...) works in nested functions, & how iit doesn't
这就是我一直认为省略号在嵌套函数中起作用的方式:当您通过省略号将一组参数传递给函数时,调用堆栈上它的任何附属函数都可以获取这些参数——我认为, 通过它自己的省略号。我相信传递给省略号的参数会累积,因此最里面的省略号包含调用堆栈中任何优于它的函数中通过省略号参数传递的所有参数。
但我刚刚做了一个实验来证实这一点,现在看来是错误的。因此:
> 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]
,您根据正常范围规则下的搜索路径,仅获取遇到的 …
的第一个实例。但我不得不说,这对我来说似乎不太可能。如果这是真的,那么,例如,如果其中一个中间函数有一个 …
参数,则提供给绘图函数的图形参数多次调用将遭受神秘的失败。
所以我想知道在 dot-dot-dots 中寻找范围参数是否有一些特殊的规则,例如如果本地实例为空则寻找高级实例,或者如果您查看 …
对于特定的命名参数,说 list(...)$my_parameter
,但没有找到它。这些解决方案都没有让我觉得很合理,但是,好吧,none 我想出的解决方案。
关于此主题的先前问题似乎主要集中在各种边缘情况上。我正在寻找更多了解正常情况下的传递规则(但可能有多层调用)。
必须明确提供省略号才能传递给嵌套函数,例如,在您的 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
我希望论坛能让我post回答并且仍然接受iod的回答。这是我的意图。
看来我最初的信念——这些点累积了调用堆栈中提供给它们的所有参数——是正确的,前提是省略号 (...
) 包含在 both 中 第一个附属的所有调用的函数定义和函数调用。请参阅下面的代码。对我来说,这表明 ... 应该定期将参数添加到嵌入其他函数的函数调用中,如果链下某处的辅助函数可能需要在顶层提供的无法识别和传递的参数显式地在编写函数时。如果读到这篇文章的人有充分的理由相信这是个坏主意,我想听听。
请注意,尽管在函数 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
这就是我一直认为省略号在嵌套函数中起作用的方式:当您通过省略号将一组参数传递给函数时,调用堆栈上它的任何附属函数都可以获取这些参数——我认为, 通过它自己的省略号。我相信传递给省略号的参数会累积,因此最里面的省略号包含调用堆栈中任何优于它的函数中通过省略号参数传递的所有参数。
但我刚刚做了一个实验来证实这一点,现在看来是错误的。因此:
> 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]
,您根据正常范围规则下的搜索路径,仅获取遇到的 …
的第一个实例。但我不得不说,这对我来说似乎不太可能。如果这是真的,那么,例如,如果其中一个中间函数有一个 …
参数,则提供给绘图函数的图形参数多次调用将遭受神秘的失败。
所以我想知道在 dot-dot-dots 中寻找范围参数是否有一些特殊的规则,例如如果本地实例为空则寻找高级实例,或者如果您查看 …
对于特定的命名参数,说 list(...)$my_parameter
,但没有找到它。这些解决方案都没有让我觉得很合理,但是,好吧,none 我想出的解决方案。
关于此主题的先前问题似乎主要集中在各种边缘情况上。我正在寻找更多了解正常情况下的传递规则(但可能有多层调用)。
必须明确提供省略号才能传递给嵌套函数,例如,在您的 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
我希望论坛能让我post回答并且仍然接受iod的回答。这是我的意图。
看来我最初的信念——这些点累积了调用堆栈中提供给它们的所有参数——是正确的,前提是省略号 (...
) 包含在 both 中 第一个附属的所有调用的函数定义和函数调用。请参阅下面的代码。对我来说,这表明 ... 应该定期将参数添加到嵌入其他函数的函数调用中,如果链下某处的辅助函数可能需要在顶层提供的无法识别和传递的参数显式地在编写函数时。如果读到这篇文章的人有充分的理由相信这是个坏主意,我想听听。
请注意,尽管在函数 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