f=function(s,abc=0,def=0) {
return(s+def)
}
f(3)
[1] 3
f(3,d=4)
[1] 7
为什么R将“d”与“def”匹配?
是否有一条规则规定,当在函数中找不到变量的名称时,R 将自动匹配大写字母与其相同的名称?
这在 R 语言定义的参数匹配部分中进行了描述。
本小节适用于闭包,但不适用于原始函数。后者通常会忽略标签并进行位置匹配,但应查阅其帮助页面以了解例外情况,包括 log、round、signif、rep 和 seq.int。
函数评估中发生的第一件事是将形式与实际或提供的参数匹配。这是通过三遍过程完成的:
标签上的精确匹配。对于每个命名提供的参数,在形式参数列表中搜索名称完全匹配的项目。相同的形式参数匹配多个实际值是错误的,反之亦然。
标签的部分匹配。使用部分匹配将每个剩余的命名提供参数与剩余的形式参数进行比较。如果提供的参数的名称与形式参数的第一部分完全匹配,那么这两个参数被认为是匹配的。有多个部分匹配是错误的。注意 if
f <- function(fumble, fooey) fbody
, thenf(f = 1, fo = 2)
是非法的,即使第二个实际参数只匹配fooey
。f(f = 1, fooey = 2)
虽然是合法的,因为第二个参数完全匹配并且不考虑部分匹配。如果形式参数包含“...”,则部分匹配仅适用于它之前的参数。位置匹配。任何不匹配的形式参数都按顺序绑定到未命名的提供参数。如果有一个 '...' 参数,它将占用剩余的参数,无论是否标记。
有三种主要的方法来匹配参数。这些在R Language Definition的Argument Matching部分进行了讨论,我在下面复制了相关部分:
函数评估中发生的第一件事是将形式与实际或提供的参数匹配。这是通过三遍过程完成的:
- 标签上的精确匹配。对于每个命名提供的参数,在形式参数列表中搜索名称完全匹配的项目。相同的形式参数匹配多个实际值是错误的,反之亦然。
- 标签上的部分匹配。使用部分匹配将每个剩余的命名提供参数与剩余的形式参数进行比较。如果提供的参数的名称与形式参数的第一部分完全匹配,那么这两个参数被认为是匹配的。有多个部分匹配是错误的。注意 if
f <- function(fumble, fooey) fbody
, thenf(f = 1, fo = 2)
是非法的,即使第二个实际参数只匹配fooey
。f(f = 1, fooey = 2)
虽然是合法的,因为第二个参数完全匹配并且不考虑部分匹配。如果形式参数包含...
,则部分匹配仅适用于它之前的参数。- 位置匹配。任何不匹配的形式参数都按顺序绑定到未命名的提供参数。如果有
...
参数,它将占用剩余的参数,无论是否标记。
请注意,这是正常功能发生的情况。原始函数在 R 中是特殊的。原始函数在许多方面都很特殊,并且总是不使用标签,而是使用位置匹配。然而,这并没有始终如一地应用。
另一个重要的例外是包含参数的函数中的...
参数。如上所述,如果一个参数出现在函数的参数列表之后, 如果位置匹配未应用于这些参数...
,则必须在对该函数的调用中命名该参数。例如:
foo <- function(x, ..., y) {
y
}
传递值的唯一方法y
是在函数调用中为其命名,例如:
foo(y = 1)