S4 class 构造函数和验证

S4 class constructor and validation

我提供了一个创建 S4 class myclass 的简短代码,并确保在验证参数 param

给出的条件时创建对象
setClass("myclass", slot = c(x = "numeric"))

 #constructor
 ValidmyClass<- function(object, param = 1)
{
 if(object@x  == param) return(TRUE)
 else return("problem")

}
setValidity("myclass", ValidmyClass)

setMethod("initialize","myclass", function(.Object,...){
.Object <- callNextMethod()
validObject(.Object,...)
.Object
})

为此我收到以下错误消息 Error in substituteFunctionArgs(validity, "object", functionName = sprintf("validity method for class '%s'", : trying to change the argument list of for validity method for class 'myclass' with 2 arguments to have arguments (object)

我理解参数的问题,但我找不到解决这个问题的方法。关于setValidity的文档提到参数方法应该是"validity method; that is, either NULL or a function of one argument (object)"。因此,根据我的理解,排除了不止一个论点。

然而,这个例子背后的想法是我希望能够根据外部给定参数的值测试 myclass 对象的构造。如果要添加更多的条件,我希望有足够的灵活性,所以只需要更新功能ValidmyClass,而不必添加更多的插槽。

有效性函数必须有一个名为 object 的参数。当我需要创建一个参数函数但实际上有更多参数或数据要传递时,我通常会退回到使用闭包。这里 ValidmyClass 的实现发生了变化,现在 return 是实际的有效性函数。封闭函数的参数就是您感兴趣的一组附加参数。

setClass("myclass", slot = c(x = "numeric"))

#constructor
ValidmyClass <- function(param) {
  force(param)
  function(object) {
    if (object@x  == param) TRUE
    else "problem"
  }
}

setValidity("myclass", ValidmyClass(1))

同时在初始化时自动调用有效性函数;但是当对象创建后插槽 x 发生变化时不会。

setMethod("initialize", "myclass", function(.Object,...) {
  .Object <- callNextMethod()
  .Object
})

new("myclass", x = 2)
new("myclass", x = 1)

有关闭包的更多信息,请参阅 adv-R。尽管我认为这回答了您的问题,但我看不到此实现实际上有何帮助。当您定义 class 时,您基本上还修复了有效性函数知道的附加参数。如果您有多个 classes 可以抽象出有效性函数,那么我会使用闭包。如果你有一个 class 在运行时改变参数,我会考虑在 class 中添加一个插槽。如果您不想更改 class 定义,您可以添加一个 class list 的插槽,您可以在其中传递任意数量的值以进行测试.