S4 构造函数和原型

发布于 2024-12-11 06:30:47 字数 850 浏览 0 评论 0原文

浏览 Hadley Wickham 的 S4 wiki: https://github.com/hadley/devtools/wiki/S4

setClass("Person", representation(name = "character", age = "numeric"), 
  prototype(name = NA_character_, age = NA_real_))
hadley <- new("Person", name = "Hadley")

我们如何设计Person 的构造函数(像这样)

Person<-function(name=NA,age=NA){
 new("Person",name=name,age=age)
}

不执行此操作:

> Person()
Error in validObject(.Object) : 
  invalid class "Person" object: 1: invalid object for slot "name" in class "Person": got class "logical", should be or extend class "character"
invalid class "Person" object: 2: invalid object for slot "age" in class "Person": got class "logical", should be or extend class "numeric"

Looking through Hadley Wickham's S4 wiki:
https://github.com/hadley/devtools/wiki/S4

setClass("Person", representation(name = "character", age = "numeric"), 
  prototype(name = NA_character_, age = NA_real_))
hadley <- new("Person", name = "Hadley")

How can we design a constructor for Person (like this)

Person<-function(name=NA,age=NA){
 new("Person",name=name,age=age)
}

that doesn't do this:

> Person()
Error in validObject(.Object) : 
  invalid class "Person" object: 1: invalid object for slot "name" in class "Person": got class "logical", should be or extend class "character"
invalid class "Person" object: 2: invalid object for slot "age" in class "Person": got class "logical", should be or extend class "numeric"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一个人的旅程 2024-12-18 06:30:47

看起来答案就在您的示例中:

Person<-function(name=NA_character_,age=NA_real_){
 new("Person",name=name,age=age)
}

yield

> Person()
An object of class "Person"
Slot "name":
[1] NA

Slot "age":
[1] NA

> Person("Moi")
An object of class "Person"
Slot "name":
[1] "Moi"

Slot "age":
[1] NA

> Person("Moi", 42)
An object of class "Person"
Slot "name":
[1] "Moi"

Slot "age":
[1] 42

但是,这相当不符合 S4,并且重复了类定义中已分配的默认值。也许您更愿意

Person <- function(...) new("Person",...)

牺牲不带命名参数的调用能力?

It looks like the answer is right there in your example:

Person<-function(name=NA_character_,age=NA_real_){
 new("Person",name=name,age=age)
}

yields

> Person()
An object of class "Person"
Slot "name":
[1] NA

Slot "age":
[1] NA

> Person("Moi")
An object of class "Person"
Slot "name":
[1] "Moi"

Slot "age":
[1] NA

> Person("Moi", 42)
An object of class "Person"
Slot "name":
[1] "Moi"

Slot "age":
[1] 42

However, that is fairly un-S4 and duplicates the default values already assigned in the class definition. Maybe you'd prefer to do

Person <- function(...) new("Person",...)

and sacrifice the ability to call without named arguments?

绅士风度i 2024-12-18 06:30:47

我更愿意为最终用户提供一些有关参数类型的提示,而不是建议使用 @themel 的 ... 。还放弃原型并使用 length(x@name) == 0 作为字段未初始化的指示,使用 People 类而不是 Person,反映了 R 的向量化结构,并在构造函数中使用 ...,因此派生类也可以使用构造函数。

setClass("People",
    representation=representation(
        firstNames="character",
        ages="numeric"),
    validity=function(object) {
        if (length(object@firstNames) != length(object@ages))
            "'firstNames' and 'ages' must have same length"
        else TRUE
    })

People = function(firstNames=character(), ages=numeric(), ...)
    new("People", firstNames=firstNames, ages=ages, ...)

People(c("Me", "Myself", "I"), ages=c(NA_real_, 42, 12))

I'd prefer giving the end-user some hints about argument types than the suggestion to use ... by @themel. Also forgoing the prototype and using length(x@name) == 0 as an indication that the field is un-initialized, using a People class rather than Person, reflecting the vectorized structure of R, and using ... in the constructor so derived classes can also use the constructor.

setClass("People",
    representation=representation(
        firstNames="character",
        ages="numeric"),
    validity=function(object) {
        if (length(object@firstNames) != length(object@ages))
            "'firstNames' and 'ages' must have same length"
        else TRUE
    })

People = function(firstNames=character(), ages=numeric(), ...)
    new("People", firstNames=firstNames, ages=ages, ...)

And

People(c("Me", "Myself", "I"), ages=c(NA_real_, 42, 12))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文