我想适当的方法是在签名中使用“ANY”:
setGeneric("foo",function(x) standardGeneric("foo"))
setMethod("foo","numeric",function(x) "numeric")
setMethod("foo","ANY",function(x) "ANY")
> foo(1)
[1] "numeric"
> foo()
[1] "ANY"
> foo(NULL)
[1] "ANY"
确保您指定了您想要处理的所有其他可能性,因为“ANY”还会处理所有不适合其他方法签名的其余部分。
如果您有可能缺少的参数,您可以不在 setMethods 的签名中指定它们并在泛型中设置默认值。在我看来,这是一个更好的设计选择。
setGeneric("foo",function(x,y=NULL,...) {
standardGeneric("foo")
})
setMethod("foo",c("numeric","ANY"),function(x,y,...) {
print(y)
})
setMethod("foo",c("numeric","numeric"),function(x,y,...) {
x + y
})
> foo(1)
NULL
> foo(1,3)
[1] 4
> foo(1,NULL)
NULL
现在您可以像处理缺少的参数一样处理代码中的 NULL 案例。
附注:现在我添加了 NULL 作为默认值,但在许多情况下,默认值有更明智的选择。请记住 setMethod 采用初始签名,并且当 y 设置为 NULL 时,这不会被默认替换。
例如:
setGeneric("bar",function(x,y=2,...) {
standardGeneric("bar")
})
setMethod("bar",c("numeric","ANY"),function(x,y,...) {
x + y
})
setMethod("bar",c("numeric","numeric"),function(x,y,...) {
x - y
})
> bar(1)
[1] 3
> bar(1,2)
[1] -1
> bar(1,NULL) # this y is not replaced with the default!
numeric(0)
肮脏的黑客:
我觉得这种方法有点尴尬,但这是一个肮脏的技巧,将所有缺少的参数设置为 NULL :
setGeneric("foo",function(x,y,z) {
pars <- names(formals(foo))
for(i in pars){
tryerr <- try(get(i),silent=T)
if(is(tryerr,"try-error")){ assign(i,NULL)}
}
standardGeneric("foo")
}
试试这个,你得到:
> foo(1)
[1] "numeric"
> foo(NULL)
[1] "NULL"
> foo()
[1] "NULL"
所以你再也不会派人去失踪了。你可以忘记它。但这不是适当的做事方式......