0

我一直试图在对象的有效性方面取得领先。我已经阅读了Hadley 的高级编程并得到了他所说的瞄准你的脚(用枪):

R 并不能保护你免受自己的伤害:你可以很容易地射中自己的脚,但如果你不把枪对准你的脚并扣动扳机,你就不会有问题。

所以这适用于S3。寻找更严格的实现,我研究了S4. 手册页setValidity显示以下内容:

setClass("track",
      representation(x="numeric", y = "numeric"))
t1 <- new("track", x=1:10, y=sort(stats::rnorm(10)))
## A valid "track" object has the same number of x, y values
validTrackObject <- function(object) {
if(length(object@x) == length(object@y)) TRUE
else paste("Unequal x,y lengths: ", length(object@x), ", ",
           length(object@y), sep="")
}
## assign the function as the validity method for the class
setValidity("track", validTrackObject)
## t1 should be a valid "track" object
validObject(t1)
## Now we do something bad
t2 <- t1
t2@x <- 1:20
## This should generate an error
## Not run: try(validObject(t2))

底线:如果我不将 validObject 添加到初始化程序或构造函数中,我将无能为力。Martin Morgan 和 bioconductor 的 Seth Falcon 的这篇文章也很有趣,尽管我总是可以t2@x <- 1:1111

我想我对此无能为力吗?尽管matrix例如课程让我想知道是否有选择。

a <- matrix(c(1:12),3,4)
cbind(a,"somechar")
# or similarily
a[1,1] <- "b"

显然 a 的所有元素matrix都必须属于同一类。所以这就是为什么一旦添加了一个字符,所有元素都被强制为共同的分母,即 class character

所以我的问题是:这怎么可能?矩阵类以哪种方式定义,它可以以任何方式保护“所有元素的某个类”的限制?有没有办法对自定义类实施这种限制?

例如:类“customlist”的类必须是一个命名列表,并且名称被限制为只有两个字符长。

4

1 回答 1

1

AFAIK,没有办法阻止您(或您的用户)通过分配做愚蠢的事情,除非可能覆盖<-. 由于这是原始的,并且对 R 来说非常基础,如果你沿着这条路走,就有破坏其他东西的危险。

如果您使用参考类,那么您可以包含允许在分配之前进行检查的访问器。

trackFactory <- setRefClass(
  "track",
  fields = list(
    x = "numeric",
    y = "numeric"
  ),
  methods = list(
    initialize = function(x, y)
    {
      assertIsValid(x, y)
      x <<- x
      y <<- y
    },
    assertIsValid = function(x, y)
    {
      if(length(x) != length(y)) 
      {
        stop(
          "Unequal x,y lengths: ", 
          toString(c(length(x), length(y)))
        )
      }
    },
    setX = function(x)
    {
      assertIsValid(x, .self$y)
      x <<- x
    },
    setY = function(y)
    {
      assertIsValid(.self$x, y)
      y <<- y
    }
  )
)

track1 <- trackFactory$new(1:10, runif(10))
track1$setX(1:5)
## Error in assertIsValid(x, .self$y) : Unequal x,y lengths: 5, 10

不幸的是,您仍然可以使用直接分配来跳过检查。

track1$x <- 1:7
于 2013-10-03T12:28:29.087 回答