混合...与s4泛型方法中的正式args

qed*_*qed 3 r ellipsis s4

来自?dotsMethods:

 Beginning with version 2.8.0 of R, S4 methods can be dispatched
 (selected and called) corresponding to the special argument “...”.
 Currently, “...” cannot be mixed with other formal arguments:
 either the signature of the generic function is “...” only, or it
 does not contain “...”.  (This restriction may be lifted in a
 future version.)
Run Code Online (Sandbox Code Playgroud)

以下是EBImage包中的一些代码:

## image IO, display
setGeneric ("image", function (x, ...) standardGeneric("image") )

## statistics
setGeneric ("hist", function (x, ...) standardGeneric("hist") )
Run Code Online (Sandbox Code Playgroud)

这显然违反了“...” cannot be mixed with other formal arguments规则.这是否意味着限制已被解除但没有记录?

Mar*_*gan 5

您引用的部分中的关键字是"已发送".这里

setGeneric("foo", function(x, ...) standardGeneric("foo"))
Run Code Online (Sandbox Code Playgroud)

你可以根据'x'类来编写方法.

.A = setClass("A", "integer")
.B = setClass("B", "integer")
setMethod("foo", "A", function(x, ...) "foo,A-method")
Run Code Online (Sandbox Code Playgroud)

'...'仍可用于,例如,提供特定于方法的参数,但没有可用于"..."的调度

setMethod("foo", "B", function(x, barg, ...) sprintf("barg=%d", barg))
Run Code Online (Sandbox Code Playgroud)

> foo(.B(), barg=123)
[1] "barg=123"
Run Code Online (Sandbox Code Playgroud)

这就是EBImage使用"......"的方式,这是一个非常常见的用例.

这里

setGeneric("bar", function(...) standardGeneric("bar"))
Run Code Online (Sandbox Code Playgroud)

如果所有类都相同,你可以编写在"..."上发送的方法

setMethod("bar", "A", function(...) "bar,A-method")
Run Code Online (Sandbox Code Playgroud)

> bar(.A(), .A())
[1] "bar,A-method"
> bar(.A(), .B())
Error in standardGeneric("bar") : 
  no method or default matching the "..." arguments in bar(.A(), .B())
> setMethod("bar", c("A", "B"), function(...) "bar,A,B-method")
Error in matchSignature(signature, fdef) : 
  more elements in the method signature (2) than in the generic signature (1) for function 'bar'
Run Code Online (Sandbox Code Playgroud)

上面使用隐式规则来确定签名,并且输出的参数显示getGeneric()在输出指示"可以为参数定义方法:"的位置,例如,

> getGeneric("foo")
standardGeneric for "foo" defined from package ".GlobalEnv"

function (x, ...) 
standardGeneric("foo")
<environment: 0x2ba550a0>
Methods may be defined for arguments: x
Use  showMethods("foo")  for currently available ones.
> getGeneric("bar")
standardGeneric for "bar" defined from package ".GlobalEnv"

function (...) 
standardGeneric("bar")
<environment: 0x2c127e58>
Methods may be defined for arguments: ...
Use  showMethods("bar")  for currently available ones.
Run Code Online (Sandbox Code Playgroud)

R似乎让你定义在x上混合的派遣的泛型......

> setGeneric("baz", function(x, ...) standardGeneric("baz"), 
             signature=c("x", "..."))
[1] "baz"
Run Code Online (Sandbox Code Playgroud)

但实际情况并非如此

> getGeneric("baz")
standardGeneric for "baz" defined from package ".GlobalEnv"

function (x, ...) 
standardGeneric("baz")
<environment: 0x2c704cc0>
Methods may be defined for arguments: x
Use  showMethods("baz")  for currently available ones.
Run Code Online (Sandbox Code Playgroud)